所有延期完成后调用方法?

时间:2014-06-16 13:38:13

标签: javascript jquery promise jquery-deferred

我有这堂课:

(function(){
"use strict";

var FileRead = function() {
    this.init();
};


p.read = function(file) {

    var fileReader = new FileReader();
    var deferred = $.Deferred();

    fileReader.onload = function(event) {
        deferred.resolve(event.target.result);
    };

    fileReader.onerror = function() {
        deferred.reject(this);
    };

    fileReader.readAsDataURL(file);

    return deferred.promise();

};

lx.FileRead = FileRead;
}(window));

在循环中调用该类:

var self = this;
    $.each(files, function(index, file){
        self.fileRead.read(file).done(function(fileB64){self.fileShow(file, fileB64, fileTemplate);});

    });

我的问题是,有没有办法在循环完成后调用一个方法,并且self.fileRead已经返回它,因为循环中的所有内容都被延迟了?

我希望它调用该方法,即使一个或多个延迟失败。

4 个答案:

答案 0 :(得分:3)

$。when允许你将多个promises包装成一个。其他承诺库有类似的东西。构建一个由fileRead.read返回的promise数组,然后将该数组传递给$ .when并将/ done / fail / always方法挂钩到.when返回的promise中

    // use map instead of each and put that inside a $.when call
    $.when.apply(null, $.map(files, function(index, file){
        // return the resulting promise
        return self.fileRead.read(file).done(function(fileB64){self.fileShow(file, fileB64, fileTemplate);});

    }).done(function() {  

      //now everything is done 
    })

答案 1 :(得分:0)

var self = this;
var processFiles = function (data) {
    var promises = [];
    $.each(files, function (index, file) {
        var def = data.fileRead.read(file);
        promises.push(def);
    });
    return $.when.apply(undefined, promises).promise();
}

self.processFiles(self).done(function(results){ 
    //do stuff
});

$.when说“当所有这些承诺得到解决时......做点什么”。它需要无限(可变)数量的参数。在这种情况下,你有一系列的承诺;

答案 2 :(得分:0)

我知道这已关闭,但正如$.when的文档所述:在多个Deferreds案例中,其中一个Deferred被拒绝,jQuery。当立即为其激活failCallbacks延期。 (立即强调是我的)

如果你想完成所有 Deferreds即使失败了,我相信你需要在下面这些行中提出你自己的插件。 $.whenComplete函数需要一个返回JQueryPromise函数数组。

    var whenComplete = function (promiseFns) {
        var me = this;
        return $.Deferred(function (dfd) {
            if (promiseFns.length === 0) {
                dfd.resolve([]);
            } else {
                var numPromises = promiseFns.length;
                var failed = false;
                var args;
                var resolves = [];

                promiseFns.forEach(function (promiseFn) {
                    try  {
                        promiseFn().fail(function () {
                            failed = true;
                            args = arguments;
                        }).done(function () {
                            resolves.push(arguments);
                        }).always(function () {
                            if (--numPromises === 0) {
                                if (failed) {
                                    //Reject with the last error
                                    dfd.reject.apply(me, args);
                                } else {
                                    dfd.resolve(resolves);
                                }
                            }
                        });
                    } catch (e) {
                        var msg = 'Unexpected error processing promise. ' + e.message;
                        console.error('APP> ' + msg, promiseFn);
                        dfd.reject.call(me, msg, promiseFn);
                    }
                });
            }
        }).promise();
    };

答案 3 :(得分:0)

为了满足要求,“即使一个或多个延迟失败也要调用方法”你理想地想要一个.allSettled()方法,但是jQuery没有特定的糖,所以你必须这样做一份DIY工作:

您可以使用$.allSettled().when()的组合查找/编写.then()实用程序或达到相同的效果,如下所示:

var self = this;
$.when.apply(null, $.map(files, function(index, file) {
    return self.fileRead.read(file).then(function(fileB64) {
        self.fileShow(file, fileB64, fileTemplate);
        return fileB64;//or similar
    }, function() {
        return $.when();//or similar
    });
})).done(myMethod);

如果它存在,$.allSettled()会在内部做类似的事情。

接下来,“在myMethod中,如何区分错误的良好反应?”,但这是另一个问题:)