Javascript 按顺序运行承诺:每个承诺在前一个承诺结束后开始

Javascript 按顺序运行承诺:每个承诺在前一个承诺结束后开始,javascript,node.js,promise,q,es6-promise,Javascript,Node.js,Promise,Q,Es6 Promise,这个问题有很多答案,但大多数答案都与承诺的解决同步(即执行的结束,而不是执行的开始) 假设我们已经有一系列函数: var funcs = [foo, bar, baz, qux]; 如何在不执行函数的情况下创建这样的数组?我试过这个: var promises = []; for (i = 0 ; i < 3, ++i){ promises.push( someFunction(i) ) } function someFunction(i) { return new P

这个问题有很多答案,但大多数答案都与承诺的解决同步(即执行的结束,而不是执行的开始)

假设我们已经有一系列函数:

var funcs = [foo, bar, baz, qux];
如何在不执行函数的情况下创建这样的数组?我试过这个:

var promises = [];
for (i = 0 ; i < 3, ++i){
    promises.push( someFunction(i) )
}

function someFunction(i) {
    return new Promise((resolve, reject) => {
        console.log(i);
        resolve(i);
    });
}
---------------------------------------------------------------- 更新(使用异步函数的简单解决方案):
实现这一点的简单方法是使用
async
函数和
wait
。有关在循环中调用承诺的示例,请参见,其中在解析前一个承诺时将调用每个承诺。

您只需传递函数名,而不传递参数。 在您的示例中,您调用

      someFunction(i) 
-传递参数i,因此这是一个函数调用。 您应该只按函数名推送函数。每个函数的参数都是在前面的承诺中解析的值

function someFunction(i) {
    return new Promise((resolve, reject) => {
        console.log(i);
       resolve(i+1); // increase the value here
   });
}
这样,参数将被传递给下一个增加1的函数。但是对于链中的第一个函数,应该传递参数。 差不多

 someFunction(0).then(someFunction).then(someFunction)
(在此解决方案中,您不需要阵列。)

问题是

promises.push( someFunction(i) )
在填充
promises
数组时,每次在将
someFunction
的值传递给
.push
方法之前,都会调用
someFunction
。因此,它可以根据需要提前执行

一个解决办法就是不要叫它。这不容易实现,所以我在考虑一个小的(但丑陋的)黑客。我引入了一个对象
{p:…,val:…}
,它包含一个promise函数和该promise函数的值。如果要提供多个值,只需传递一个数组。该方法将其转换为函数参数。函数
callPromise
以正确的方式处理函数的执行

可能有人提出了更好的解决方案,但这是一个我可以很快想到的解决方案

下面是一个按顺序调用承诺的示例。我添加了一个额外的函数(如果您有另一个函数有多个参数),作为PoC

var承诺=[];
for(设i=0;i<3;++i){
push({p:someFunction,val:i});
}
push({p:anotherFunction,val:[100,33]});
push({p:someFunction,val:4});
功能(一){
返回新承诺((解决、拒绝)=>{
log('someFunction,i:'+i);
决议(i);
});
}
函数另一个函数(i1,i2){
返回新承诺((解决、拒绝)=>{
log('anotherFunction,i1:'+i1+',i2:'+i2);
决议(i);
});
}
函数调用承诺(prom){
if(Object.prototype.toString.call(prom.val)!='[Object Array]')prom.val=[prom.val];
返回prom.p.apply(null,prom.val);
}
log('before-loop');
let result=callPromise(promises[0]);
for(设i=1;i<1.length;++i){
result=result.then(callPromise(promises[i]));

}
检查这个答案:我认为内置promise API没有这个功能。你可以试试Promise.reduce by bluebird:@KarelG:正是我的问题!如何将它推入数组而不调用它?我想动态地在for循环中创建这些承诺。
for(让I=0;I<3,++I){funcs.push(()=>someFunction(I))}
可以。@Bergi:我不认为这会在等待前一个函数被解决的情况下连续运行它们。那么我以后如何才能按顺序正确调用这些函数呢?@Ari您想让同一个函数执行3次吗?是的,使用不同的参数。@Ari链中的每个函数都应负责通过解析值将参数传递给下一个函数。第一个可以使用要开始的参数调用的参数。你能解释一下callPromise到底在做什么吗?@Ari
prom
{p:…,val:…}
对象。它首先检查val是否为数组。如果不是,则将其设置为数组。然后使用
.apply
,使用val数组运行函数
p
。如果您检查它的文档,就会发现数组是作为参数提供给函数p的。该函数返回一个promise,然后可以像promise一样处理它:使用
。然后使用
。catch
等。。。
promises.push( someFunction(i) )