在所有的promise被调用之后,通过jQuery Deferreds循环

我目前正在尝试使用HTML5 FileAPI构buildfile upload器。 file upload器应该处理多个文件,并显示图像预览,如果该文件是一个图像。

由于FileReader类asynchronous工作,我想等到所有的文件都被读取。 所以我使用了Deferreds。

读取文件的方法是返回一个承诺。 另一种方法循环遍历所有文件,并将所有的承诺推送到一个数组中。 然后,我将所有的promise都添加到我的数组中,然后应用then()方法。

现在到我的问题。 由于then()方法只被调用一次 ,当我得到所有的承诺。 我没有机会处理每一个承诺。 我想要做的是,一旦他们都在那里循环所有的承诺,并返回结果。

这是我的FileProcessor对象

read: function(file) { var reader = new FileReader(); var deferred = $.Deferred(); reader.onload = function(event){ deferred.resolve(event.target.result); }; reader.onerror = function() { deferred.reject(this); } if(/^image/.test(file.type)) reader.readAsDataURL(file); return deferred.promise(); }, 

这里是FileManager对象的handleFileSelect()方法,它应该调用FileProcessor.read()方法。

 handleFileSelect: function(e){ var $fileList = $('#file-list'); var files = e.target.files; var promises = []; //Promises are going to be stored here var filestring = ''; var processedFile; // Loop trough all selected files for(var i = 0; i < files.length; i++){ // Store the promise in a var... processedFile = FileProcessor.read(files[i]); // And push it into the array where the promises are stored promises.push(processedFile); } // Once all deferreds have been fired... $.when.apply(window, promises).then(function(){ for(var i = 0; i < promises.length; i++){ // PROBLEM HERE: I need to get the // result from my resolved Deferred // of every single promise object console.log(promises[i]); } }); }, 

我是否使用错误的方法来推迟和承诺? 难道他们不应该像我试图做的那样使用吗?有没有更好的方法来达到我的目的?

我是否使用错误的方法来推迟和承诺?

是。 在asynchronouscallback中,您不应该访问promises ,而只能使用callback参数。 $.when .resolve()的返回承诺会使用数组中的每个.resolve()参数的数组来parsing – 您可以遍历arguments对象来访问结果:

 $.when.apply($, promises).then(function () { for (var i = 0; i < arguments.length; i++) { var singleresult = arguments[i][0]; console.log(singleresult); } }); 

您可以使用参数对象来引用promise对象返回的所有值

 $.when.apply($, promises).then(function () { for (var i = 0; i < arguments.length; i++) { var data = arguments[i][0]; // PROBLEM HERE: I need to get the // result from my resolved Deferred // of every single promise object console.log(data); } }); 

我看你已经接受了一个答案,但你可能想知道你的handleFileSelect方法可以大大简化如下

 handleFileSelect: function(e) { var promises = $.map(e.target.files, function(file) { return FileProcessor.read(file); }); $.when.apply(window, promises).then(function() { $.each(arguments, function(i, a) { console.log(a[0]); }); }); }, 

当然,当你处理结果时,它会变得更加复杂,但这应该给你一个很好的简洁的基础。