2014-09-13 62 views
1

Jquery的$.when函数在解决所有promise时执行'done'回调,但如果其中任何一个导致错误,则不执行回调。一旦所有的承诺产生了结果successerror,我该如何执行'完成'回调?

+0

看到http://jsfiddle.net/arunpjohny/kdLbLq25/2/ – 2014-09-13 19:38:15

回答

1

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

请允许我用更准确的术语来重新说明这一点。

jQuery的$.when需要承诺 和返回一个新的承诺列表。当所有这些承诺满足时,新承诺满足,或者当这些承诺中的任何承诺被拒绝时,拒绝

您正在查看的函数被称为“Settle”,并且在jQuery的承诺实现中不可用 - 幸运的是,我们可以轻松地添加它。

的策略是:

  • 创建一个新的承诺明确。
  • 让一个计数器开始于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或deferreds其也有望jQuery中)

相关问题