简体   繁体   English

map function 中的异步等待未按顺序执行

[英]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.

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