Reputation: 41
Is there any way to not use await inside loop for following code?
const redirects = ['redirectId1'];
for (let i = 0; i < redirects.length; i++) {
const promiseResult = await anAsyncFunction(redirects[i]);
if (promiseResult.redirects) {
redirects.forEach(newRedirect => {
if (!redirects.includes(newRedirect)) redirects.push(newRedirect);
});
}
}
I've tried using Map
const redirects = ['redirectId1'];
const promiseArr = redirects.map(async redirect => {
const promiseResult = await anAsyncFunction(redirect);
if (promiseResult.redirects) {
redirects.forEach(newRedirect => {
if (!redirects.includes(newRedirect)) redirects.push(newRedirect);
});
}
});
await Promise.all(promiseArr);
but in doing so, code executes further before newRedirect
is pushed to redirects array
thus not calling anAsyncFunction
for new added value.
I want to know if there any possible way to achieve this?
Upvotes: 1
Views: 47
Reputation: 417
If u are interested that each redirect batch will be in parallel and keep asking for more redirects as long as there is, u can achieve it as following :
const handleRedirects = async (_redirects) => {
const newRedirects = [];
await Promise.all(
_redirects.map(async (redirect) => {
const promiseResult = await anAsyncFunction(redirect);
if (promiseResult.redirects) {
promiseResult.redirects.forEach((newRedirect) => {
if (!_redirects.includes(newRedirect)) newRedirects.push(newRedirect);
});
}
})
);
return newRedirects;
};
const run = async () => {
const redirects = ['redirectId1'];
let newRedirects = [ ...redirects ];
do {
newRedirects = await handleRedirects(newRedirects);
redirects.push(...newRedirects);
} while (newRedirects.length)
}
Upvotes: 0
Reputation: 370989
If the idea is to send out each request as soon as possible, without waiting for earlier requests to resolve first, you can use a recursive async function that calls itself when the result contains redirects:
const recurse = (redirects) => Promise.all(
redirects.map(r => anAsyncFunction(r)
.then(({ redirects }) => {
if (redirects) {
return recurse(redirects);
}
})
)
);
// pass in the initial array:
await recurse(redirects);
If you also need to use the populated outer redirects
array later, then:
const recurse = (redirects) => Promise.all(
redirects.map(r => anAsyncFunction(r)
.then(({ redirects }) => {
return redirects
? recurse(redirects).then(res => [redirects, res])
: [];
})
)
);
// pass in the initial array:
const allRedirects = [initialRedirects, await recurse(initialRedirects)].flat(Infinity);
Upvotes: 1