JavaScript – Async Iterator & Generator
前言
要看懂這篇請先看下面幾篇
JavaScript – Generator Function
JavaScript – 用 Generator 執行非同步函式 & await async
Async Iterator (es2018)
es6 推出的 Iterator + for...of 非常好用, 但是它只能執行同步程式碼. 不支援非同步程式設計.
顧名思義 Async Iterator 就是 Iterator 的 Async 版本. 它支援非同步程式設計.
我們來看看 sync 和 async Iterator 的對比
sync Iterable
const iterable: Iterable<string> = { [Symbol.iterator]() { let index = 0; return { next() { index++; if (index === 10) { return { done: true, value: '', }; } return { done: false, value: 'value' + index }; }, }; }, };for (const value of iterable) { console.log('value', value); }
async Iterable
const asyncIterable: AsyncIterable<string> = { [Symbol.asyncIterator]() { let index = 0; return { async next() { return new Promise((resolve) => { setTimeout(() => { index++; if (index === 10) { resolve({ done: true, value: '', }); } return resolve({ done: false, value: 'value' + index }); }, 1000); }); }, }; }, }; (async () => { const asyncIterator = asyncIterable[Symbol.asyncIterator](); const { value, done } = await asyncIterator.next(); console.log([value, done]); for await (const value of asyncIterable) { console.log('value', value); } })();
和 sync iterable 的區別是
1. 屬性是 Symbol.asyncIterator
2. iterator next 返回的是一個 promise, promise 的返回才是 done 和 value
3. 遍歷的方式是 for await ... of
你可能會認為, sync iterable 也可以返回 promise 丫.
的確. 在 JavaScript – 用 Generator 執行非同步函式 & await async 裡有提到如何用 Generator + Iterator + Promise + 自執行 Generator 來實現非同步程式設計 (async await 語法糖的背後的原理)
它的 iterator next value 返回的就是 promise. 但不要忘了, 還有 done 屬性呢? 這個總不能返回 Promise 了丫. 所以還是有細微區別的.
Async Generator (es2018)
和 Async Iterator 一樣概念. Generator 也有 Async 版本.
function delayAsync(time: number, value: string) { return new Promise((resolve) => { setTimeout(() => { resolve(value); }, time); }); } async function* myGenerator() { yield delayAsync(1000, 'a'); console.log('do something'); yield delayAsync(1000, 'b'); } (async () => { const asyncIterator = myGenerator(); for await (const value of asyncIterator) { console.log(value); } // 1000ms after log a // do something // another 1000ms after log b })();
和 sync Generator 的區別是
1. async function* 多了 async 關鍵字開頭
2. yield 返回 Promise
3. 可以用 for await...of 遍歷