【问题标题】:Deferred chains in jqueryjquery中的延迟链
【发布时间】:2017-03-17 03:09:17
【问题描述】:

我需要连续发出 3 个请求。所以为此我使用 jquery defered。

Request 1 
-> on done if response contains expected result then Request 2 else return empty array/null
-> on done if response contains expected result then Request 3 else return empty array/null

private request1() {
    const vm = this;

    vm.isLoading(true);
    let deffer = system.defer(dfd => {dataService.getResponse1()
       .done((response) => {
              request2(response.collection))
              dfd.resolve();
       });

    return deffer.promise();
}

private request2(collection) {
     dataService.getResponse2(collection)
        .done((response) => request3(response.collection));
}

private request3(collection) {
     dataService.getResponse3(collection)
        .done((response) => saveResponse(response.collection));
}

private saveResponse(collection) {
    //do some stuff    
}

在构造函数中我调用request1

vm.request1().done(() => {
      vm.isLoading(false);
});

问题是isLoading 在调用saveResponse 之前被设置为false。在所有请求完成后,我应该如何正确重构我的请求结构以更新 isLoading

谢谢。

【问题讨论】:

标签: javascript jquery typescript jquery-deferred chaining


【解决方案1】:

试试这个方法(请查看代码中的cmets):

// Request 1 -> on done Request 2 -> on done -> Request 3

private request1() {
    const vm = this;

    vm.isLoading(true);
    let deffer = system.defer(dfd => {dataService.getResponse1()
       .done((response) => {
              // 1. Here you have to resolve the dfd promise after 
              // request2 promise is resolved. For this reason,
              // I added the call to "done()" method.
              request2(response.collection)).done((response2) => { dfd.resolve()});
       });

    return deffer.promise();
}

private request2(collection) {
     // 2. You need to return the promise returned by getResponse2
     return dataService.getResponse2(collection)
        .done((response) => request3(response.collection));
}

private request3(collection) {
     // 3. You need to return the promise returned by getResponse3
     return dataService.getResponse3(collection)
        .done((response) => saveResponse(response.collection));
}

private saveResponse(collection) {
    //do some stuff    
}

因此,在request3() 中,您返回由getResponse3() 返回的承诺,而后者又返回由在done() 方法中调用的saveResponse() 返回的承诺。

request2() 中,您返回由getResponse() 返回的promise,而后者又返回由上一段中描述的request3() 返回的promise。

request1() 中,在主要的 done() 回调中,您调用 request2() 并等待(使用 done())它完成,然后再解决主要的承诺。

这样vm.isLoading(false)应该在request2request3完成后调用。

【讨论】:

  • 对您所做的更改以及它如何提供帮助的一些描述将是一个好主意。
  • 只是添加它;)
  • 您的解决方案对我有用。但是您对@mab 评论有什么看法 - 将 deferred 作为参数传递是否很好?谢谢
  • @demo 我很高兴我的解决方案对你有用。我不喜欢在函数之间传递延迟。我更喜欢将 deferred 保留在创建它的函数中,并更改所有函数以返回一个 Promise。我认为让所有具有异步操作的函数都返回一个承诺是一个很好的做法,因此您可以将它们链接起来。
【解决方案2】:

简短回答:在调用 saveResponse 之后,将 vm.isLoading(true); 移动到 request3 的正文中。

【讨论】:

  • 在我打电话给saveResponse之前似乎已经设置了vm.isLoading(false);
猜你喜欢
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多