4 ms·
Does the article’s final code behave in a desired way? To my understanding, it simply catches rejections, but for-await block still waits for every promise in o
by wruza 4y ago
Does the article’s final code behave in a desired way? To my understanding, it simply catches rejections, but for-await block still waits for every promise in order, up until the rejected one. Your `finally` block gets called too late, unless I miss something obvious.
To make this loop early-cancellable on any out-of-order rejection, I’d create a helper generator and a “semaphore” promise, which would block the yield until there’s a next resolved value or any rejection.
const arr = []
arr.length = promises.length
let step, sem
function rearm() {
sem = new Promise(res => {step = res})
}
rearm()
promises.forEach((p, i) => {
p.then(v => step({i, v}))
.catch(e => step({i, e}))
})
async function* values() {
let next = 0
while (next < arr.length) {
if (arr[next]) {
yield arr[next++].v
continue
}
const {i, v, e} = await sem
rearm()
if (e) {
yield Promise.reject(e)
return
}
arr[i] = {v}
}
}
try {
for await (… of values()) {
…
I barely ever used js generators specifically, so this code is more like a concept (e.g. I suspect a race around rearm()), but you get the idea.