嵌套延期呼叫

时间:2014-05-28 00:30:20

标签: javascript jquery jquery-deferred

基本上这就是我在伪代码中要做的事情:

Fetch AsyncResultA
  If Success
    Fetch 
      AsyncResultB
      AsyncResultC
    Either Success/Fails
      Display any successful results
  If Fails
    Display error

这就是我在jQuery中所做的,但它不起作用:

        $.when (

          fetchA()

        ).then (function (data, textStatus, jqXHR) {

            return {
              xhrObject1: [data, textStatus, jqXHR],
              xhrObject2: fetchB(),
              xhrObject3: fetchC(),
              xhrObject4: fetchD()
            }

          }, fail

        ).always( displayResults );

注意:

所有fetch函数都是AJAX调用。

displayResults将获取成功获取的数据并立即显示所有数据。因此,只要fetchA成功,就会显示一些内容。

fail只会在fetchA失败时被调用,从而取消任何进一步的提取。

1 个答案:

答案 0 :(得分:3)

它不起作用,因为你没有从.then回调中返回一个承诺,而是一个普通的对象。这导致displayResults基本上被fetchA返回的原始承诺调用。 documentation(强调我的)的相关部分:

  

从jQuery 1.8开始,deferred.then()方法返回一个新的promise [...]。这些过滤器函数可以返回一个新值以传递给promise .done().fail()回调,或者它们可以返回另一个可观察对象(Deferred,Promise等),将其已解决/拒绝的状态和值传递给承诺的回调

使用$.when并返回其返回值:

fetchA().then(function () {
    return $.when([].slice.call(arguments), fetchB(), fetchC(), fetchD());
}, fail).always( displayResults );

$.when返回一个在传递给自身的所有promise都被解析(或拒绝)时解析的promise。因此,如果只传递一个参数,则没有理由使用$.when

如果您在displayResults失败时不想执行fetchA,则可以单独绑定失败处理程序:

fetchA().fail(fail).then(function () {
    return $.when([].slice.call(arguments), fetchB(), fetchC(), fetchD());
}).always( displayResults );