产生一个依赖于递归Promise的Promise

IT技术 javascript angularjs asynchronous promise q
2021-02-25 08:47:36

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

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

我需要为这些 id 中的每一个执行异步远程调用。每个调用都是使用 $resource 执行的 WebAPI 请求,并作为Promise呈现。

我需要创建一个接受这些 ID 数组的函数,然后初始化递归Promise链。该链应该为每个 ID 一个接一个地产生相应的 webapi 调用。这些调用不应该是并行的,而是链接的。

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

我怎样才能在 angularjs 中做到这一点?

2个回答

您使用reduceover 数组将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([]));
ES6: a.reduce((p,c) => p.then(a => makeRequest(c)).then(res => arr.concat([res])), Promise.resolve([]))
2021-04-22 08:47:36
@BenjaminGruenbaum:几乎,这是一个arr参数,而不是a
2021-04-25 08:47:36
哦+1,巧妙地使用promise解析为空数组。
2021-05-01 08:47:36
@AskarIbragimov 我的回答不使用 Q 构造函数。如果你想用 Bergi 的方式来做,但你可以用 $q$q.when([])代替Q([])
2021-05-06 08:47:36
这是Q函数用于创建从课程的valuePromise- O等待,你正在使用angularjs ......$q.when也应该这样做
2021-05-08 08:47:36

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

我们在没有特定.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这里有一个方法,它发出单个请求并返回一个在该请求完成时实现的Promise。

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

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
 });