Node.js readstream中的“end”事件被发出两次
我试图在nodejs中将文件上传到mongodb的gridfs。这是我的一段代码:Node.js readstream中的“end”事件被发出两次,node.js,gridfs,Node.js,Gridfs,我试图在nodejs中将文件上传到mongodb的gridfs。这是我的一段代码: var fs = require('fs'); var gridfs = require('gridfs-stream'); var mongo = require('mongodb'); var gfs; mongo.Db.connect('mongodb://...', function (err, db) { console.log('*** connect to upload files');
var fs = require('fs');
var gridfs = require('gridfs-stream');
var mongo = require('mongodb');
var gfs;
mongo.Db.connect('mongodb://...', function (err, db) {
console.log('*** connect to upload files');
gfs = gridfs(db, mongo);
var fpath = req.files.image_file.path;
var fname = id + '_' + req.files.image_file.name;
console.log('*** final name = ' + fname);
var writestream = gfs.createWriteStream({ filename: fname });
var readstream = fs.createReadStream(fpath);
readstream.on('open', function () {
console.log('*** stream opened');
readstream.pipe(writestream);
});
readstream.on('end', function () {
console.log('*** file upload finished');
doCSUpdate();
});
readstream.on('error', function() {
console.log('*** error occured');
doCSUpdate();
});
});
doCSUpdate是另一个函数
问题是,在日志中,我看到文件上传完成出现了两次,而流只打开了一次
13:21:30 web.1 | *** connect to upload files
13:21:30 web.1 | *** final name = ...
13:21:30 web.1 | *** stream opened
13:21:30 web.1 | *** file upload finished
13:21:30 web.1 | *** file upload finished
这会导致doCSUpdate运行两次,这有时会导致发送错误后无法设置标题,因为响应设置了两次。我知道这很晚,但我认为这可能对未来的搜索者有用 可能[file upload finished]消息出现了两次,因为上传是分块完成的,就像您将大小合适的东西上传到GridFS时一样。快速解决方法是使用一个guard子句来防止函数再次运行 我之前遇到过这个问题,readstream的“data”事件被多次发出,导致节点抱怨[错误:发送头后无法设置头]。下面这样简单的方法可能会有所帮助
var doCSUpdateAlreadyCalled = false;
...
if (! doCSUpdateAlreadyCalled){
doCSUpdateAlreadyCalled = true;
doCSUpdate();
}
我正在使用类似的代码,尽管我正在关注可写流上的close事件,而不是可读流的end流。我不知道为什么结尾会被触发两次。@robertklep,它工作正常吗?正如我从文档中了解到的,并不是每个流都会发出关闭事件。但它并没有描述哪些流可以和哪些流不可以……是的,对我来说,类似的情况也适用:将通过Express上传的文件存储在GridFS中。