In the following code, when the condition within the loop is satisfied we can't really be sure in which order are both asyncFunction called.
siblings.forEach(function(sibling, index) {
// This condition may only be satisfied once (only one sibling may have data-selected true)
if (sibling.getAttribute('data-selected') == 'true') {
asyncFunction(sibling);
}
})
asyncFunction(element);
Since I know asyncFunction() returns a promise I could chain those to ensure the order:
asyncFunction(sibling).then(asyncFunction(element));
But how to do this taking the condition into account?
I considered wrapping the loop in a promise that resolves when the condition is satisfied or after the loop ends, but it seems a tad convoluted.
// Untested
function checkSiblings(siblings) {
let promise = new Promise(function(resolve, reject) {
siblings.forEach(function(sibling, index) {
if (sibling.getAttribute('data-selected') == 'true') {
resolve(asyncFunction(sibling));
}
})
resolve();
})
}
checkSiblings(siblings).then(asyncFunction(element));
I am sure this has been addressed before, but I can't find the right search keyboards.
Thank you
If only one of the siblings can meet the criteria, using find
will simplify your code:
const selected = [...siblings].find( elem => elem.getAttribute('data-selected') == 'true' );
Mark checkSiblings
as async
so it always returns a Promise, and have it return the asyncFunction
Promise when appropriate:
return selected ? asyncFunction(selected) : null;
Then you can chain them as before:
checkSiblings(siblings).then(() => asyncFunction(element));
All together you'd have something like this:
async function checkSiblings (siblings) {
const selected = [...siblings].find( elem => elem.getAttribute('data-selected') == 'true' );
return selected ? asyncFunction(selected) : null
}
checkSiblings(siblings).then(() => asyncFunction(element));
There are several ways. One of them is using Array.reduce
to resolve promises sequentially :
[...siblings].reduce(
async (prev, sibling)) => {
// Await initial/previous promise (discard results)
await prev;
// This condition may only be satisfied once
// (only one sibling may have data-selected true)
if (sibling.getAttribute('data-selected') == 'true') {
// Return the async function promise
return asyncFunction(sibling);
}
// async functions always returns a promise.
// No need to return anything
// Initial promise autoresolved
}, Promise.resolve())
// Once all have been executed
.then( () => asyncFunction(element));
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.