Javascript 在调用所有承诺后循环jQuery延迟

Javascript 在调用所有承诺后循环jQuery延迟,javascript,jquery,jquery-deferred,deferred,Javascript,Jquery,Jquery Deferred,Deferred,我目前正在尝试使用HTML5 FileAPI构建一个文件上传程序。如果文件是图像,文件上传程序应该处理多个文件并显示图像预览 因为FileReader类是异步工作的,所以我想等到所有的文件都被读取了。因此,我使用延迟 读取文件的方法正在返回承诺。另一种方法循环遍历所有文件,并将所有承诺推送到一个数组中。然后,在将所有承诺添加到数组中后,我将应用Then()方法 现在来谈谈我的问题。因为then()方法只有一次调用,当我得到所有承诺时。我没有机会履行每一个承诺。我想做的是,一旦我的承诺都实现了,就

我目前正在尝试使用HTML5 FileAPI构建一个文件上传程序。如果文件是图像,文件上传程序应该处理多个文件并显示图像预览

因为FileReader类是异步工作的,所以我想等到所有的文件都被读取了。因此,我使用延迟

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

现在来谈谈我的问题。因为then()方法只有一次调用,当我得到所有承诺时。我没有机会履行每一个承诺。我想做的是,一旦我的承诺都实现了,就把它们循环一遍,然后返回结果

这是我的文件处理器对象

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();
},
下面是文件管理器对象的handleFileSelect()方法,该方法应该调用FileProcessor.read()方法

handleFileSelect:函数(e){
var$fileList=$(“#文件列表”);
var files=e.target.files;
var promissions=[];//承诺将存储在这里
var filestring='';
var处理文件;
//循环所有选定文件
对于(var i=0;i
我是否使用了错误的方法来履行延期和承诺?它们不应该像我正在尝试的那样使用吗?有没有更优雅的方法来实现我的目的?

您可以使用来引用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);
    }
});
$.when.apply($,promises).then(function(){
for(var i=0;i
我是否使用了错误的方法来履行延期和承诺

对。在异步回调中,您不应该访问
承诺
,而应该只访问回调参数。的返回承诺使用数组中每个承诺的
.resolve()
参数数组进行解析-您可以通过循环访问结果:

$.when.apply($, promises).then(function () {
    for (var i = 0; i < arguments.length; i++) {
        var singleresult = arguments[i][0];
        console.log(singleresult);
    }
});
$.when.apply($,promises).then(function(){
for(var i=0;i
我知道您已经接受了答案,但您可能想知道您的
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]);
        });
    });
},

当然,当您充实结果处理时,它将再次变得更加复杂,但这将为您提供一个非常简洁的基础。

谢谢!这个答案很有帮助。我希望当我接受@Bergi的回答时,你不会因为进一步的问题而生气explanation@ThomasDavidPlat没问题:)谢谢!因此,在事后循环我的承诺是完全可以的?不是通过
承诺
(这没有多大帮助-它们只是你无法直接访问其值的承诺),而是通过回调的参数-这是每个承诺的结果。为什么不进一步简化为
$.when.apply($,$.map)(e.target.files,FileProcessor.read))。然后(…)
?:-)就可以了,但对我来说,我们在这一点上遇到了可读性问题。
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]);
        });
    });
},