我在express.js上使用jQuery文件上传,使用jquery-file-upload-middleware,mongoose使用mongoDB。
我想上传galery的图片。 Galery对象包含一个Image对象数组,例如
var GalerySchema = new mongoose.Schema({
images: [ImageSchema]
})
每个文件异步上传后,我想把它推入我的Galery对象的图像数组中。
我尝试执行以下服务器端:
// Is called everytime an image is uploaded
upload.on('end', function(fileInfo, rew, res){
// Get the galery
db.Galery.findOne({_id: req.fields.galery_id}, function(err, galery){
// Create new Image object instance
var image = new db.Image({src: fileInfo.name});
// Save, in order to create auto generated _id
image.save(function(err){
if(err) {console.log(err); return; }
// Add to Images array of Galery object
galery.images.push(image);
// Save galery with added image
galery.save(function(err){
if(err) { console.log(err); return; }
});
})
});
});
这样做,我得到一个众所周知的[VersionError: No matching document found.]
,根据我目前的知识,这是由于同时访问同一个mongodb文档,因为上传是异步发生的。
因此,为了处理问题的异步方式,最好等待所有上传完成,然后将图像逐个插入到mongodb中,即使用async.parallel()
。< / p>
但是如何访问已完成所有上传的事件?
我知道浏览器方面我可以使用Mongoose group query in node.js / express route。但首先,这不包含有关上传文件的任何数据。另外,我想在服务器端做这件事。
是否有像
这样的东西upload.on('doneAll', function(allFilesInfo, req, res){...})?
答案 0 :(得分:0)
您可以使用promises(Bluebird:https://github.com/petkaantonov/bluebird, npm install bluebird --save )并使用以下内容:
libcrypto.dylib
答案 1 :(得分:0)
由于jQuery文件上传正在为每个文件创建一个XHR,因此这些文件在服务器端被视为单独的POST,并且上传中间件无法直接知道所有上载何时完成。您可以创建另一个端点作为停止事件的回调,但不仅缺少有关上传内容的信息,如您所知,但如果有两个或更多用户碰巧,它也无法提供帮助。同时上传。
我认为您需要使用findOneAndUpdate(或findByIdAndUpdate)来对Galery
执行更新。有关如何$push
image
到galery
的示例,请参阅此answer。
答案 2 :(得分:0)
如果您使用sequentialUploads: true
,则上传您每个文件向服务器发出一个请求或总共一个请求。如果您想知道所有图像何时在异步场景中上传,您需要使用express定义一个额外路由,并在完成调用此路由的所有文件后向fileuploader添加回调。然后,您还需要跟踪上传和未保存的文件。如果您的脚本由多个人使用(公共访问?),那么您还需要实现一些会话处理,以保存在调用“uploadDone”路由时要添加的上载文件。如您所见,这是一个很大的开销,所以我建议使用sequentialUploads: true
解决方案。
但是我几乎不相信你得到[VersionError: No matching document found.]
因为同时访问图库文档,因为获取/保存文档只需几毫秒。我建议你检查是否发送了req.fields.galery_id
。
console.log(req.fields.galery_id);