iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
1
Modern Web

JavaScript 之旅系列 第 14

JavaScript 之旅 (14):Async Iterators

  • 分享至 

  • xImage
  •  

本篇介紹 ES2018 (ES9) 提供的 async iterators (非同步迭代器)。

在 ES2015 (ES6) 引入了 iterator interface,spec 的定義如下:必須要有 next(),其回傳值必須符合 IteratorResult interface

下面是 IteratorResult interface 的定義,需有以下 property:

  • done:Boolean 值
    • 代表 iterator 的 next() 呼叫的結果狀態
    • 若 iterator 已到最後,則 donetrue
    • 若 iterator 未到最後,則 donefalse
  • value:任何值
    • donefalse,則 value 為當前迭代元素值 (iteration element value)
    • donetrue,則 value 則為 iterator 的回傳值 (若沒有回傳值則 valueundefined )

例如:建立一個 generator 函數,呼叫該 generator 函數時,會回傳 Generator 物件,此物件實作了 Iterable interfaceIterator interface,所以也可說是建立新的 iterator 物件,接著就可呼叫 iterator 上的 next()

function* generatorFunc() {
  yield 'first';
  yield 'second';
}

let iterator = generatorFunc();
console.log(iterator);
// generatorFunc {<suspended>}

console.log(iterator.next());
// {value: "first", done: false}
console.log(iterator.next());
// {value: "second", done: false}
console.log(iterator.next());
// {value: undefined, done: true}

但過去的 iterator 只適合處理同步資料,需要 I/O 存取的資料都會透過 event-based 或 streaming 非同步 API 來處理,但 iterator 不能處理非同步資料。

若是 promise 的 iterator 也不行處理,因為只能非同步處理 value,但不能非同步處理 done 狀態,也就是說下一個值根本就還沒確定,怎麼會知道有沒有 done 呢?而且 value 可能也還沒拿到。

為了給非同步資料提供通用的存取 protocol,此提案引入了 AsyncIterator interface、async iteration statement ( for-await-of ) 和 async generator function。

async iterators & async iterables

AsyncIterator interfaceIterable interface 很像,只是將 next() 回傳的值變為 IteratorResult 物件的 Promise,spec 的定義如下:

所以原本同步的 iterator 可以直接從 next() 回傳的 IteratorResult 物件拿到 valuedone

const { value, done } = syncIterator.next();
console.log(value);
console.log(done);

而非同步 iterator 因為是 Promise,所以可以這樣處理:

asyncIterator.next()
  .then(({ value, done }) => {
    console.log(value);
    console.log(done);
  });

資料來源


上一篇
JavaScript 之旅 (13):Object Rest/Spread Properties
下一篇
JavaScript 之旅 (15):Optional catch binding
系列文
JavaScript 之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言