jquery '$.when':即使在出错的情况下如何触发'done'回调

jquery '$.when': how to trigger 'done' callback even in case of error

本文关键字:情况下 回调 出错 done 何触发 when jquery      更新时间:2023-09-26

Jquery的$.when函数在解析所有承诺时执行'done'回调,但如果其中任何一个导致错误,则不执行。一旦所有承诺都有结果,我该如何执行"完成"回调,无论是success还是error

Jquery 的 $.when 函数在解析所有承诺时执行"done"回调,但如果其中任何一个导致错误,则不会执行。

请允许我用更准确的术语重新表述这一点。

jQuery的$.when接受承诺1的列表返回一个新的承诺。当所有这些承诺都实现时,新承诺就会实现,或者当任何这些承诺被拒绝时,这个新承诺就会实现

你正在寻找的函数叫做"Settle",在jQuery的promise实现中不可用 - 幸运的是我们可以很容易地添加它。

策略是:

  • 显式创建新承诺。
  • 保持计数器从n开始 - 参数的数量。
  • 对于每个参数:
    • 如果不是承诺,请立即分配它并减少计数器。
    • 如果是承诺,请等待它解决,然后递减计数器。
  • 当计数器达到 0 时,解决承诺。

$.settle = function(promises){
    var count = arguments.length; // how many we'll have to wait for
    var d = $.Deferred(); // the new deferred - representing the return value
    var results = []; // what we'll end up resolving with
    $.map(arguments, function(arg, i){
        if(typeof arg.then !== "function"){ // it's not a promise!
            results[i] = {status:"fulfilled", value: arg}; 
            count--; // and we don't have to wait for it
        } else {
            arg.then(function(value){
                results[i] = {status:"fulfilled", value: value };
                count--;
                if(count === 0) d.resolve.apply(d, results); // resolve promise
            }, function(e){
                results[i] = {status:"rejected", reason: e };
                count--;
                if(count === 0) d.resolve.apply(d, results); // resolve promise
            });
        }
    })
    return d.promise(); // return a promise over the deferred
}

上述用法应如下所示:

$.settle($.get("firstUrl"),$.get("secondUrl")).then(function(firstResult, secondResult){
     // access results here, values are in firstResult.value
     // and you can tell if it rejected or fulfilled in firstResult.status
);

我不是这里的语义的忠实粉丝 - 但我试图让它们尽可能接近 jQuery 的语义$.when

(1. 或延期,这也是 jQuery 中的承诺(