[英]Async await in map function not executing in order
I have the follow code below:我有以下代码:
var arr = [ { condition: true, recursion: [], result: 'OLD_RESULT', recursiveArray: [{condition: true, result: 'OLD_RESULT'}] }, {condition: false, result: 'OLD_RESULT'}, { condition: true, recursion: [], result: 'OLD_RESULT', recursiveArray: [{condition: true, result: 'OLD_RESULT'}] }, {condition: false, result: 'OLD_RESULT'}, ]; var someAsyncCall = async () => { return 'NEW VALUE'; }; var asyncInMap = (arr) => { return arr.map(async (elem) => { const condition = elem.condition; if (condition) { const result = await someAsyncCall(); elem.result = result; } if (elem.recursiveArray) { elem.recursion = asyncInMap(elem.recursiveArray); } console.log('SECOND:', elem); return elem; }); }; console.log('FIRST'); var promisesVal = asyncInMap(arr); console.log('THIRD'); var completedVal = await Promise.all(promisesVal); console.log('FOURTH', completedVal);
My question is in the order of the console.log's
I am getting:我的问题是我得到的
console.log's
顺序:
FIRST
SECOND: {condition: false, result: "OLD_RESULT"}
SECOND: {condition: false, result: "OLD_RESULT"}
THIRD
SECOND: {condition: true, recursion: Array(1), result: "NEW VALUE", recursiveArray: Array(1)}
SECOND: {condition: true, recursion: Array(1), result: "NEW VALUE", recursiveArray: Array(1)}
SECOND: {condition: true, result: "NEW VALUE"}
SECOND: {condition: true, result: "NEW VALUE"}
FOURTH (4) [{…}, {…}, {…}, {…}]
Why is the Third
log being printed before all the Second
console.log
are done?为什么在所有
Second
console.log
完成之前打印Third
日志? Is this because I am using recursion inside of the asyncInMap
function along with async/await
?这是因为我在
asyncInMap
function 中使用递归以及async/await
吗? Ideally the asyncInMap
should be completed (with all the Second
logs printed first) and then only the Third
log should be printed correct?理想情况下,应该完成
asyncInMap
(首先打印所有Second
日志),然后只打印Third
日志是否正确?
that is the feature of async await
code in js.这就是js中
async await
代码的特点。 THIRD
will be called earlier than any asynchronious operation inside of that call, because event loop works like that in js. THIRD
将在该调用中的任何异步操作之前被调用,因为事件循环的工作方式与 js 中的一样。 But there is a mistake in your code that can make FOURTH
be logged earlier than all of the SECOND
s are complete, because you are not waiting till recursive SECOND
s are completed anywhere.但是您的代码中有一个错误可能使
FOURTH
在所有SECOND
完成之前被记录,因为您没有等到递归SECOND
在任何地方完成。 To fix that you could add await here要解决此问题,您可以在此处添加等待
elem.recursion = await Promise.all(asyncInMap(elem.recursiveArray));
also if you would like to persist the order of execution, you could do simple iterations and do all the awaiting logic at the function top level此外,如果您想保留执行顺序,您可以进行简单的迭代并在 function 顶层执行所有等待逻辑
var asyncInMap = async (arr) => {
for(const elem of arr) {
if(elem.condition) {
elem.result = await someAsyncCall();
}
if(elem.recursiveArray) elem.recursion = await asyncInMap(elem.recursiveArray);
console.log('SECOND:', elem);
}
return arr;
};
console.log('FIRST');
var promisesVal = asyncInMap(arr);
console.log('THIRD', 'calls can still be in progress here');
var completedVal = await promisesVal;
console.log('FOURTH', 'everything is completed here', completedVal);
note, that in the last example there will be no parallel operation executing at the same time.请注意,在最后一个示例中,不会同时执行并行操作。 they will be "async called" one by one in a predefined order
它们将按预定义的顺序一一被“异步调用”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.