I want to iterate the entries of a Map with an asynchronous callback function. The callback function should be started immediately for all elements.
I ended up with the following code, which works but looks too complicated:
async function test() {
const map1 = new Map();
map1.set('a', 1);
map1.set('b', 2);
map1.set('c', 3);
await Promise.all(Array.from(map1.entries()).map(async([
key,
value
]) => {
await doSomeThing(key, value);
await doSomeOtherThing(key, value);
}
}
Is there an easier way to achieve this?
You could do something shorter
Array.from(map1.entries())
could be rewritten to [...map1]
doSomeOtherThing
does not depend on doSomeThing
so we could call them two concurrentlyawait Promise.all(
[...map1].flatMap(([key, val]) => [
doSomeThing(key, val),
doSomeOtherThing(key, val),
])
)
const doSomeThing = (key, val) =>
new Promise(res => {
console.log("doSomeThing start", key, val)
setTimeout(() => {
console.log("doSomeThing finish", key, val)
res()
}, 1000)
})
const doSomeOtherThing = (key, val) =>
new Promise(res => {
console.log("doSomeOtherThing start", key, val)
setTimeout(() => {
console.log("doSomeOtherThing finish", key, val)
res()
}, 2000)
})
async function test() {
const map1 = new Map()
map1.set("a", 1)
map1.set("b", 2)
map1.set("c", 3)
/*
await Promise.all(
Array.from(map1.entries()).map(async ([key, value]) => {
await doSomeThing(key, value)
await doSomeOtherThing(key, value)
})
)
*/
await Promise.all(
[...map1].flatMap(([key, val]) => [
doSomeThing(key, val),
doSomeOtherThing(key, val),
])
)
}
test().then(() => {
console.log("done")
})
According to MDN, Promise.all() takes an iterable of promises and waits for them to resolve. An iterable may be an array, as in your code, or a dedicated generator created by a generator function. I don't know if this meets your definition of "easier", but here's one way to do it:
function* processMap(map, callback) {
for (const entry of map.entries())
yield callback(entry);
}
async function test() {
const map = new Map();
map.set("a", 1);
map.set("b", 2);
map.set("c", 3);
const processEntry = async (entry) => {
await doSomeThing(entry);
await doSomeOtherThing(entry);
};
await Promise.all(processMap(map, processEntry));
}
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