Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js readstream中的“end”事件被发出两次_Node.js_Gridfs - Fatal编程技术网

Node.js readstream中的“end”事件被发出两次

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');

我试图在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');
    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中。