Async, Await, Promises, foreachAsync
const echo = (msg, delay = 50) => new Promise((resolve) => setTimeout(() => resolve(msg), delay));
const echoUpperCase = (msg, delay = 50) => new Promise((resolve) => setTimeout(() => resolve(new Date().toISOString() + ' ' + msg.toUpperCase()), delay));
const foreachAsync = async (array, cb) => { for (let i = 0, l = array.length; i < l; i++) await cb(array[i]);};
const severalDelays = async (...msgs) => {
//msgs; // BABEL HACK https://github.com/babel/babel/issues/1882
// var ret = '';
// we can't use forEach because the await is inside another method.
// so we have to async the function
// but if it's async, we need to await it
// but it's not us that wrote forEach, so we can't.
// msgs.forEach((item) => {
// let val = await echo(item);
// ret += ' ' + val;
// });
// that leads us to :
// for (var i = 0; i < msgs.length; i++) {
// var item = msgs[i];
// let val = await echo(item);
// ret += val + ' ';
// }
// but we are smart, so we create our own forEachAsync
await foreachAsync(msgs, async (msg) => console.log(await echoUpperCase('1 ' + msg)));
// but we can use for..of actually
for (const msg of msgs) {
console.log(await echoUpperCase('2 '+ msg)); // await belongs to the main function
}
// Or play it concurrent
await Promise.all(msgs.map(async (msg) => console.log(await echoUpperCase('3 ' + msg))));
// Basically, Promise.all should be almost always use, because it naturally "await" its args
return await Promise.all(msgs.map(async (msg) => 'hello ' + await echoUpperCase('4 ' + msg)));
};
severalDelays('first!', 'second!', 'third!').then((res) => {
console.log('done!', res);
});