✅ – Adi – 08-24 Jun 22

I am making async calls inside forEach but if some calls in foreach fail then it is not running the forEach block on remaining elements. I have already wrapped forEach inside try/catch block but did not work. I used try/catch inside forEach and then it worked. code:
subs.forEach(async subscription => {
try {
const endpoint = subscription.endpoint;
const id = endpoint.substr((endpoint.length - 8), endpoint.length);
const result = await webpush.sendNotification(subscription, notificationPayload, options);
console.log(`Endpoint ID: ${id}`);
console.log(`Result: ${result.statusCode}`);
} catch (error) {
console.error("send notification error:", error)
}
});
subs.forEach(async subscription => {
try {
const endpoint = subscription.endpoint;
const id = endpoint.substr((endpoint.length - 8), endpoint.length);
const result = await webpush.sendNotification(subscription, notificationPayload, options);
console.log(`Endpoint ID: ${id}`);
console.log(`Result: ${result.statusCode}`);
} catch (error) {
console.error("send notification error:", error)
}
});
By default forEach should not return early if any async call fails is that correct? then why in above case I have to use try/catch inside forEach??
S
ScriptyChris666d ago
you tried using try..catch outside forEach? how? try..catch works for sync code. If you have async code you should use await to "make it" sync, so a promise returned by async code is "awaited"/resolved and if it throws then try..catch can handle it. In case of forEach, it executes your async code, but doesn't wait each iteration to finish, because the logic inside forEach doesn't await the callback your provide - it just executes it, ignores immediately returned promise (by async function). Hence, forEach returns undefined before your async code gets executed (including awaits inside the callback). If you had sync code inside forEach then try..catch would work, because sync code isn't wrapped in promise as with async functions Possible solution is to change forEach to map - which will return array of promises - and put it inside Promise.all, which can be awaited and this can be handled by try..catch
A
Adi666d ago
If you had sync code inside forEach then try..catch would work, because sync code isn't wrapped in promise as with async functions
Agree In my case I want to delete subscriptions i.e call delete API when subscription fails. So should I do that in catch block or first collect all the failed subscriptions and then delete them one by one?? what do you suggest?
S
ScriptyChris666d ago
if you want to delete failed subscriptions then i think you can use Promise.allSettled() instead of Promise.all() and then check status of each promise - for every failed one, delete it (your catch logic) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
UU
Unknown User665d ago