I start with a function which renders and yields a sequence of image blobs.
async function* renderAll(): AsyncIterableIterator<Blob> {
const canvases = await getCanvases();
for (const canvas of canvases) {
yield await new Promise<Blob>((resolve, reject) => {
canvas.toBlob(result => { if (result) resolve(result); else reject(); });
});
}
}
That works fine, but the performance isn't ideal because each promise has to be resolved before starting on the next operation. Instead, the caller should decide when to wait for the promises, while still preserving the order.
async function* renderAll(): AsyncIterableIterator<Promise<Blob>> {
const canvases = await getCanvases();
for (const canvas of canvases) {
yield new Promise<Blob>((resolve, reject) => {
canvas.toBlob(result => { if (result) resolve(result); else reject(); });
});
}
}
To my surprise, this fails to compile because "Type Blob is not assignable to type Promise<Blob>." Further inspection shows that the yield operator unpacks promises within an async function, such that yield promise is functionally identical to yield await promise.
Why does the yield operator act this way? Is it possible to yield a sequence of promises from an async iterator?