【问题标题】:Dojo promise all -- but that waits for all promises to returnDojo 承诺所有——但这要等待所有承诺返回
【发布时间】:2014-11-19 22:45:58
【问题描述】:

我正在使用带有延迟的 dojo 承诺。我有一个 Promise/all 可以捕获所有的 Promise,并且仅在它们全部成功或其中任何一个返回错误时执行。有没有办法拥有一个只在所有都执行时才返回的承诺列表(无论它们是成功还是错误)?我想要一个失败的列表,而不是“其中一个失败”。

我想我可以解决所有的延迟、错误或成功,但这有点违背了目的......

【问题讨论】:

    标签: javascript ajax dojo promise


    【解决方案1】:

    有两种选择:

    解决

    Dojo 承诺没有提供任何工具来明确地管理这种情况,比如'bluebird's Promise.settle 或 when's when.settle。所以我们几乎必须自己创建它:

    function settle(promises){ // assuming "dojo/promise/all" and "dojo/Deferred"
        var d = new Deferred();
        var countdownLatch = promises.length; 
        var results = [];
        promises.forEach(function(p, i){ 
            p.then(function(v){
                results[i] = {state: "fulfilled", value: v};
                countdownLatch--;
                if(countdownLatch === 0) d.resolve(results);
            }, function(err){
                results[i] = {state: "rejected", err: err };
                countdownLatch--;
                if(countdownLatch === 0) d.resolve(results);
            });
        });
        return d; // dojo mixes deferred and promises because it's an older API
    }
    

    这会让你这样做:

    settle(myPromisesArray).then(function(results){
        results.forEach(function(res){
            console.log(res.state); // you can `if` on it to check a particular promise
        });
    });
    

    反映

    更现代的方法是创建一个反射方法,该方法接受一个承诺并返回一个承诺,该承诺总是与包含前一个承诺状态的对象实现。这是 Bluebird 正在探索的方向,可能会包含在 V3 中。

    function reflect(promise){
        return promise.then(function(v){ return {state: "fulfilled", value: v }; },
                            function(e){ return {state: "rejected" , error: e }; });
    }
    

    这可以让您进行不同的聚合,这使得上面的 settle 成为一个私人案例:

    function settle(promises){
        return all(promises.map(reflect));
    }
    

    【讨论】:

    • @Skitterm 只是现代 Promise 库的一个示例(快两个数量级,更好的跟踪等)
    • 根据this page,您应该返回deferred.promise而不是deferred,(在您的情况下为d.promise
    【解决方案2】:

    如您所见,一旦取消其中一个组成承诺,dojo/promise/all 就会实现。

    你想要dojo/DeferredList - 这可以配置为你想要的,你可以从中提取promise对象。

    【讨论】:

    • 谢谢。不幸的是,DeferredList 已被弃用。
    • 是的。不过,如果您不打算升级到 Dojo 2.0,那也没关系。
    • ...令人惊讶的是,仍然没有 Dojo 2.0 :)
    猜你喜欢
    • 1970-01-01
    • 2014-03-12
    • 2020-03-26
    • 1970-01-01
    • 2017-06-24
    • 2014-06-14
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多