【问题标题】:Produce a promise which depends on recursive promises产生一个依赖于递归承诺的承诺
【发布时间】:2014-05-14 09:08:09
【问题描述】:

我有一个整数 id 数组,例如

var a=[1,2,3,4,5]

并且我需要为每个 ID 执行异步远程调用。每个调用都是使用 $resource 执行的 WebAPI 请求,并以 Promise 的形式呈现。

我需要创建一个函数来获取这些 ID 的数组,然后初始化递归承诺链。该链应该会导致每个 ID 的相应 webapi 调用,一个接一个。这些调用不应该是并行的,而是链式的。

有问题的函数返回一个“主要”承诺,应根据异步 Web 调用的结果解决或拒绝该承诺。也就是说,如果递归中的某个承诺由于与服务器断开连接而被拒绝,则主承诺也应该失败。在正常情况下,“main”promise 必须在所有请求完成时解决。

如何在 angularjs 中实现这一点?

【问题讨论】:

标签: javascript angularjs asynchronous promise q


【解决方案1】:

您在数组上使用reduce 将promise 链接在一起。没有必要使这个递归。

// for angularjs: var Q = $q.when;
var p = a.reduce(function(prev, el) {
    return prev.then(function(arr) {
        return makeRequest(el).then(function(res) {
             return arr.concat([res]);
         });
    });
}, Q([]));

【讨论】:

  • 哦 +1,巧妙地使用 promise 解决了空数组。
  • ES6: a.reduce((p,c) => p.then(a => makeRequest(c)).then(res => arr.concat([res])), Promise.resolve([]))
  • @BenjaminGruenbaum:几乎是arr 参数而不是a
  • 当然是 the Q function 从一个值创建一个承诺 - 哦等等,你正在使用 angularjs…$q.when 应该做同样的事情
  • @AskarIbragimov 我的回答不使用 Q 构造函数。如果您想按照 Bergi 的方式进行操作,但使用 $q 您可以使用 $q.when([]) 而不是 Q([])
【解决方案2】:

这其实是一个非常合理的要求。

我们在没有特定.each 控件的库中使用的工具是.then:

var a = [1,2,3,4,5];
var p = makeRequest(a.shift()); // use first element
a.forEach(function(el){
    p = p.then(function(result){
        return makeRequest(el);
    });
});

p.then(function(){
    // all requests done
});

请注意,我假设您在这里有一个 makeRequest 方法,它发出一个请求并返回一个在该请求完成时履行的承诺。

如果您需要使用辅助数组,也可以返回请求的结果:

var a = [1,2,3,4,5];
var results = Array(a.length);
var p = makeRequest(a.shift()).
        then(function(res){ results[0] = res;}); // use first element
a.forEach(function(el,i){
    p = p.then(function(result){
        results[i] = result;
        return makeRequest(el);
    });
});
p = p.thenResolve(results); // resolve with results, in BB that'd be p.return(results)

p.then(function(results){
    // all requests done
    console.log(results); // array of response values
}).catch(function(e){
    // single failure
});

使用 Bluebird 库的 v2 分支,您可以:

 Promise.each([1,2,3,4,5],makeRequest).then(function(results){
      // access results
 });

【讨论】:

    猜你喜欢
    • 2019-12-07
    • 2014-11-11
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-09-26
    • 2018-05-29
    • 1970-01-01
    相关资源
    最近更新 更多