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:
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? Is this because I am using recursion inside of the asyncInMap
function along with 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?
that is the feature of async await
code in js. THIRD
will be called earlier than any asynchronious operation inside of that call, because event loop works like that in 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. 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
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.