DEV Community

Discussion on: Rebuilding Promise.all()

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Yes, this was quite unintuitive the first time I saw something like that, but you can just loop over threads, promises, etc. and wait for each one to finish, since you're ultimately waiting for the one that runs the longest anyway, and even if it comes first, the others will then just resolve instantly.

Thread Thread
 
lionelrowe profile image
lionel-rowe • Edited

I think what makes it doubly confusing is that a very common pattern for Promise.all is mapping over an array, so the callback to map takes a function resolving to a promise, even though what's directly being passed to Promise.all is the returned promises themselves.

const cb = url => fetch(url)
    .then(x => x.res())
    .then(x => x.json())

const promises = urls.map(cb)

const datas = await Promise.all(promises)
Enter fullscreen mode Exit fullscreen mode

cb is (url: String) => Promise<any>, but promises is Array<Promise<any>>, not Array<(url: String) => Promise<any>>.

To fetch and do something with each resolved object in series, you'd do this:

for (const url of urls) {
    const data = await cb(url)
    doSomething(data)
}
Enter fullscreen mode Exit fullscreen mode

Time taken: total latency of all requests.

But you could equally loop over the promises instead of the urls:

for await (const data of promises) {
    doSomething(data)
}
Enter fullscreen mode Exit fullscreen mode

Time taken: max latency of any one request.

Maybe this is just spelling out the obvious for some people but personally I still find it somewhat unintuitive, until you have that lightbulb moment 💡