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到底在做什么吗?@Ariprom
是{p:…,val:…}
对象。它首先检查val是否为数组。如果不是,则将其设置为数组。然后使用.apply
,使用val数组运行函数p
。如果您检查它的文档,就会发现数组是作为参数提供给函数p的。该函数返回一个promise,然后可以像promise一样处理它:使用。然后使用和。catch
等。。。
promises.push( someFunction(i) )