简体   繁体   English

foreach具有多种功能的异步

[英]foreach async with multiple functions

I have this issue where i can't make order in async foreach promise. 我有一个问题,我无法在异步foreach许诺中下订单。 Hope you can help me. 希望您能够帮助我。

I have 3(promises) functions that i want to run in the foreach before running them again. 我有3个(承诺)函数,我想在再次运行它们之前在foreach中运行。

Code below: 代码如下:

 var env = [ 'dev', 'prd', 'tst', ] env.forEach(currentEnv => { Promise.resolve() .then(firstFunction(currentEnv)) .then(secondFunction(currentEnv)) }); function firstFunction(env) { new Promise(resolve => { setTimeout(() => { console.log('firstFunction ' + env) resolve(); }, 2000); }).catch((error) => { console.log('something went wrong' + env + "error: " + error); }); }; function secondFunction(env) { new Promise(resolve => { setTimeout(() => { console.log('secondFunction ' + env) resolve(); }, 1000); }).catch(() => { console.log('something went wrong') }); } 

Outcome: 结果:

secondFunction dev
secondFunction prd
secondFunction tst
firstFunction dev
firstFunction prd
firstFunction tst

expected: 预期:

firstFunction dev
secondFunction dev
firstFunction prd
secondFunction prd
firstFunction tst
secondFunction tst

Hope you guys can help me. 希望你们能帮助我。

First of all you need to actually return promises from your functions and provide functions (not results of function calls) to .then() callbacks. 首先,您需要实际从函数返回promise,并将函数(不是函数调用的结果)提供给.then()回调。

 var env = [ 'dev', 'prd', 'tst', ] env.forEach(currentEnv => { Promise.resolve() .then(() => firstFunction(currentEnv)) .then(() => secondFunction(currentEnv)) }); function firstFunction(env) { return new Promise(resolve => { setTimeout(() => { console.log('firstFunction ' + env) resolve(); }, 2000); }).catch((error) => { console.log('something went wrong' + env + "error: " + error); }); }; function secondFunction(env) { return new Promise(resolve => { setTimeout(() => { console.log('secondFunction ' + env) resolve(); }, 1000); }).catch(() => { console.log('something went wrong') }); } 

Doing that is enough to make your calls to be in order "all firstFunction() calls then all secondFunction() calls". 这样做足以使您的调用按照“所有firstFunction()调用然后所有secondFunction()调用”的secondFunction()

But if you need to make next environment to wait for the completion of work of the current one, you may use async iterator construction. 但是,如果您需要使下一个环境等待当前环境的完成,则可以使用异步迭代器构造。 It's relatively new feature, so I assume that you're using at least Node 10.x. 这是一个相对较新的功能,因此我假设您至少使用Node10.x。

 var env = [ 'dev', 'prd', 'tst', ]; function firstFunction(env) { return new Promise(resolve => { setTimeout(() => { console.log('firstFunction ' + env) resolve(); }, 2000); }).catch((error) => { console.log('something went wrong' + env + "error: " + error); }); }; function secondFunction(env) { return new Promise(resolve => { setTimeout(() => { console.log('secondFunction ' + env) resolve(); }, 1000); }).catch(() => { console.log('something went wrong') }); } async function *getAsyncIterator(env) { for (const currentEnv of env) { await firstFunction(currentEnv); await secondFunction(currentEnv); yield currentEnv; } } async function doStuff() { for await (const currentEnv of getAsyncIterator(env)) { console.log(`Complete work on ${currentEnv}`) } } doStuff(); 

UPDATE: 更新:

And finally, the third option is applying a recursive algorithm, in case when some older node version must be supported. 最后,在必须支持某些较旧的节点版本的情况下,第三个选择是应用递归算法。

 var env = [ 'dev', 'prd', 'tst', ]; function firstFunction(env) { return new Promise(resolve => { setTimeout(() => { console.log('firstFunction ' + env) resolve(); }, 2000); }).catch((error) => { console.log('something went wrong' + env + "error: " + error); }); }; function secondFunction(env) { return new Promise(resolve => { setTimeout(() => { console.log('secondFunction ' + env) resolve(); }, 1000); }).catch(() => { console.log('something went wrong') }); } function doStuff(env = []) { if (env.length === 0) return; const [ currentEnv, ...restEnvs ] = env; return Promise.resolve() .then(() => firstFunction(currentEnv)) .then(() => secondFunction(currentEnv)) .then(() => doStuff(restEnvs)); } doStuff(env).then(() => console.log('job done')); 

Hi and thank you so much guys for your help. 嗨,非常感谢你们的帮助。 I have been playing a little and came up with this solution: 我玩了一段时间,想出了以下解决方案:

let promise = Promise.resolve();
env.forEach(thisEnv => {
  promise = promise
    .then(() => firstFunction(thisEnv))
    .then(() => secondFunction(thisEnv))
});

promise.then(() => {
  doneBuilding()
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM