有没有办法在$ .when(...)中检查承诺的个别结果,而不管最终状态如何

时间:2014-04-27 08:48:59

标签: javascript jquery ajax deferred

检查以下示例

$.when(a1, a2, a3, a4, .....)
       .done(function (){alert('done')})
       .fail(function (){alert('fail')});

如果所有的a1-ax都成功了,我可以检索并处理所有“承诺”的“完成”功能中的所有数据

如果a1和a2失败,而a3和a4成功并返回一些数据。调用“失败”,并没有说实际失败的内容,也没有传递成功的值(不传递任何参数)

问题 有没有办法通过“延期”检索成功调用(a3和a4)的值(数据)(即使它失败),还是应该为每个承诺分配单独的回调?

1 个答案:

答案 0 :(得分:1)

$.when()旨在立即执行.fail(),如果传递给它的任何承诺被拒绝。因此,如果a1或a2被拒绝,它将调用.fail()并且可能还没有a3和a4的数据。这就是它的设计方式,在某些情况下确实限制了它的用途。如果您想知道每个单独的结果,无论其他承诺是否失败并且您正在使用$.when(),那么正如您所推测的那样,您需要附加自己的.done()和{{1}每个人承诺的处理程序。

巧合的是,我实现了(我自己使用)一个MultiDeferred对象,它允许你指定是否希望它在任何promise失败时立即失败(如.fail()那样)或等到所有在致电主人$.when().fail()之前,承诺已达到最终结果。这可能对你有用。

这是功能与.done()之间差异的摘要:

  1. 您可以将其配置为在所有承诺都使用$.when()方法完成之前不会调用它自己的.fail()
  2. 它有.setFailImmediate(false)方法,因此您可以为其添加更多承诺(在解决之前)。由于这些承诺通常是在循环中收集的,因此只需.add()一个而不是将它们全部收集到一个数组中,然后传递给.add()
  3. $.when()的工作方式不同。这不是回应每个单独承诺的.progress(),而是.progress(),当每个单独的承诺被拒绝或解决时触发.notify(),以便您可以跟踪每个单独的完成。如果您想要每个承诺的实际进度,您可以随时直接附加到它们。
  4. 您可以随时查询已延期的.progress()是否有任何承诺失败。
  5. 您可以使用.getFailYet()查询尚未完成的承诺数量。
  6. 注意构造函数.getRemaining()返回一个实际的Deferred对象(添加了一些额外的方法),你也可以在其上调用$.MultiDeferred()来获取promise对象(它还有额外的方法)它)。

    .promise()对象可以像这样使用:

    MultiDeferred

    工作演示:http://jsfiddle.net/jfriend00/3JN52/

    MultiDeferred对象的代码在这里:

    var d = $.MultiDeferred(a1, a2, a3, a4);
    // configure it to not fail immediately when any single promise fails
    d.setFailImmediate(false);
    // you can optionally add more promises here
    // often in a loop
    d.add(a5, a6);
    d.done(function() {
        // called when all promises have been successfully resolved
    }).fail(function() {
        // even if one promise failed, all the data from all the promises
        // is passed here as this can be configured to wait for all
        // promises to finish before calling .fail()
    });