當 ECMAScript 2015 引進 Promise 概念後,實務上會遇到 Array Promise,若要搭配 ECMAScript 2017 的 async await
,可使用 for await of
讓 Codebase 更精簡。
Version
ECMAScript 2017
Imperative
let data = [
Promise.resolve (1),
Promise.resolve (2)
]
for (let x of data)
console.log (x)
第 1 行
let data = [
Promise.resolve (1),
Promise.resolve (2)
]
data
為 Array,但其 element 都是 Promise。
第 6 行
for (let x of data)
console.log (x)
若想印出 Array 中 Promise 內的值,直覺會使用 for
loop 搭配 console.log
。
但這樣寫不會印出 1
與 2
。
await
let data = [
Promise.resolve (1),
Promise.resolve (2)
]
for (let x of data)
console.log (await x)
第 6 行
for (let x of data)
console.log (await x)
若要 console.log
印出 Promise 內部值,必須在每個 x
前加上 await
從 Promise 內取出。
for await of
let data = [
Promise.resolve (1),
Promise.resolve (2)
]
for await (let x of data)
console.log (x)
ES2017 提供了 for await of
,如此 x
已經從 Promise 中取出,console.log
可直接使用。
Promise.all
let data = [
Promise.resolve (1),
Promise.resolve (2)
]
let show = a => a.forEach (x => console.log(x))
Promise
.all (data)
.then (show)
若不想使用 async await
,對於 Array Promise 可先使用 Promise.all
處理,如此 Array Promise 中的值會先從 Promise 取出,唯 Promise.all
回傳為新的 Promise,且仍然是 Array,因此再使用 then
解開才能搭配 forEach
與 console.log
印出。
Promise.all + await
let data = [
Promise.resolve (1),
Promise.resolve (2)
]
for (let x of await Promise.all (data))
console.log (x)
Promise.all
回傳為 Promise,因此也可使用 for of await
先將 Promise.all
回傳結果解開,如此就可繼續使用 for of
。
Conclusion
for await of
比原本for of
寫法優雅,且{}
可直接使用x
,不必再一直重複await
若不喜歡使用
await
,Array Promise 可先用Promise.all
處理,別忘了其回傳仍是 Promise,因此必須接著使用then
才能取得 Promise 內部值for await of
與for of await
不太一樣,for await of
是搭配 Array Promise;而for of await
是搭配 Promise Array