在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 imagegalery

如果您使用的是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);