在所有承诺被调用之后,通过jQuery Deferreds循环 [英] Looping through jQuery Deferreds after all promises have been called

查看:154
本文介绍了在所有承诺被调用之后,通过jQuery Deferreds循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



因为FileReader类异步工作我想等到所有文件已被阅读。因此我使用Deferreds。



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



现在我的问题。因为then()方法只被称为一次,所以我得到了所有的承诺。我没有机会处理每一个承诺。我想做的是,一旦它们全部存在,就循环遍历我的所有承诺并返回结果。



这是我的 FileProcessor 对象

 读取:函数(文件){
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 Object的handleFileSelect()方法,它应该调用FileProcessor.read()方法。

  handleFileSelect:function( e){
var $ fileList = $('#file-list');

var files = e.target.files;
var promises = []; // Promise将存储在这里
var filestring ='';

var processedFile;

//循环所有选定的文件
for(var i = 0; i< files.length; i ++){
//将promise存储在var中.. 。
processedFile = FileProcessor.read(files [i]);
//并将其推送到存储承诺的数组中
promises.push(processedFile);
}

//一旦所有延期被解雇...
$ .when.apply(window,promises).then(function(){
for (var i = 0; i< promises.length; i ++){
//问题在这里:我需要得到
//来自我解决的Deferred
//每个单独的结果promise对象
console.log(promises [i]);
}
});

},

我是否使用了错误的方法来推迟和承诺?是不是应该像我正在尝试那样使用它们是否有更优雅的方式来实现我的目的?

解决方案

< blockquote>

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


是的。在异步回调中,您不应该访问 promises ,而只能访问回调参数。 $。时 的回报承诺确实解决了数组中每个promise的 .resolve()参数的数组 - 你可以遍历 参数对象以访问结果:

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


I am currently trying to build a File Uploader using the HTML5 FileAPI. The File Uploader is supposed to handle multiple files and show image previews if the file is an image.

since the FileReader class works asynchronously I want to wait until all the the files have been read. Therefore I am using Deferreds.

A method which reads the file is returning a promise. Another method loops through all files and pushes all promises into an array. Then I'm applying the then() method once all promises have been added to my array.

Now to my problem. Since the then() method is only called once, when I got all promises. I have no chance to process every single promise. What I want to do is, to loop through all my promises once they are all there and return the result.

This is my FileProcessor Object

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();
},

And here comes the FileManager Object's handleFileSelect() method that is supposed to call the FileProcessor.read() method.

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]);
        }
    });

},

Am I using the wrong approach for deferreds and promises? Aren't they supposed to be used like I'm trying to do and is there a more elegant way to achieve my purpose?

解决方案

Am I using the wrong approach for deferreds and promises?

Yes. In the asynchronous callback you should not access promises, but only the callback arguments. The return promise of $.when does resolve with an array of the .resolve() parameters for each of the promises in the array - you can loop over the arguments object to access the results:

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

这篇关于在所有承诺被调用之后,通过jQuery Deferreds循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆