I'm trying to use a function with callback in forEach loop.
I need to wait for execution to complete before moving on to next step.
Here's my code:
const arr = '6,7,7,8,8,5,3,5,1'
const id = arr.split(',');
const length = id.length;
id.forEach( (x, index) => {
(function FnWithCallback () {
setTimeout(() => { console.log(x) }, 5000);
})();
});
console.log('done');
I came up with a hack:
const arr = '6,7,7,8,8,5,3,5,1'
const id = arr.split(',');
const length = id.length;
const fn = () => {
return new Promise (resolve => {
id.forEach( (id, index) => {
setTimeout(() => {console.log(id)}, 3000);
if(index === (length - 1))
resolve();
})
})
}
fn().then(()=> {
console.log('done');
})
But the hack seems to be broken.
Can I have a real solution to this? A NPM package would be really helpful.
Note: I had a look at async.js. I'm not sure if that is something I want since I'm trying to avoid callback hell.
The solution is to promisify the callback function and then use Array.prototype.map() coupled with Promise.all():
const arr = '6,7,7,8,8,5,3,5,1'
function FnWithCallback (id, cb) {
setTimeout(cb, 1000, id)
}
const promisified = id => new Promise(resolve => {
FnWithCallback(id, resolve)
})
const promises = arr.split(',').map(promisified)
Promise.all(promises).then(id => {
console.log(id)
console.log('Done')
})
If your callback API follows the Node.js convention of (error, result) => ..., then you should use util.promisify() to promisify the function, or check the documentation to see if omitting the callback argument will cause the call to return a promise, since a lot of packages provide promise-based APIs out-of-the-box now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With