在jQuery File Upload中上传所有文件时,如何在服务器端使用stop事件
我正在使用jQueryfile upload与jqueryfile upload中间件和mongoose与mongoDB express.js。
我想上传图片。 Galery对象包含一个Image对象的数组,如
var GalerySchema = new mongoose.Schema({ images: [ImageSchema] })
在每个文件被asynchronous上传后,我想把它推到我的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文档,因为上传是asynchronous的。
所以为了处理这个问题的asynchronous方式,等待所有的上传完成,然后将这些图像一个接一个地插入到mongodb(即使用async.parallel()
。
但是,如何访问已完成的所有上传事件?
我知道浏览器端我可以使用停止事件 。 但首先这不包含有关上传文件的任何数据。 另外,我想在服务器端做。
有没有像
upload.on('doneAll', function(allFilesInfo, req, res){...})?
你可以使用promise(Bluebird: https : //github.com/petkaantonov/bluebird,npm install bluebird –save )并且有这样的一些东西:
var BPromise = require('bluebird'); var uploadDone = new BPromise(function (resolve, reject) { // your image upload }); uploadDone.then(function (result) { // upload complete here }, function (error) { console.log("Error: ", error); });
由于jQuery File Upload正在为每个文件创build一个XHR,所以这些在服务器端被视为单独的POST,并且上传中间件没有直接的方式知道所有上传何时完成。 您可能会创build另一个端点作为停止事件的callback点,但是,不仅缺less上传内容的信息,如您所知,而且如果有两个或更多用户正在上传,也不会有太大的帮助与此同时。
我相信你需要的是使用findOneAndUpdate (或者findByIdAndUpdate )调用来在Galery
上执行更新。 看到这个答案的例子,如何$push
image
到galery
。
如果您使用的是sequentialUploads: true
,则上传的每个文件或一个请求总共向服务器发出一个请求sequentialUploads: true
。 如果你想知道什么时候所有的图像都是asynchronous上传的,你需要用express定义一个额外的路由,当所有的文件完成调用这个路由的时候,给文件上载器添加一个callback。 那么你还需要跟踪哪些file upload和不保存之前。 如果您的脚本被多个人使用(公共访问?),那么当您调用“uploadDone”路由时,您还需要执行一些会话处理来保存要添加的上传文件。 正如你可以看到这是一个很大的开销,所以我会build议使用sequentialUploads: true
解决scheme。
但是我很难相信你会得到[VersionError: No matching document found.]
因为同时访问图库文档,因为获取/保存文档只需要几毫秒的时间。 我会build议你检查是否发送了req.fields.galery_id
。
console.log(req.fields.galery_id);