Promise.all()
對處理 Promise Array 非常好用,讓我們不必使用 Imperative 的 for await of
,但可惜 Promise.all()
不適合 Pipeline,Wink-fp 特別提供 all()
取代 Promise.all()
。
Version
macOS Catalina 10.15.4
VS Code 1.43.2
Quokka 1.0.285
Ramda 0.27.0
Wink-fp 1.20.67
Imperative
let data = [
Promise.resolve(1),
Promise.resolve(2)
]
let f = arr => {
for (let x of arr)
console.log(x)
}
f(data)
第 1 行
let data = [
Promise.resolve(1),
Promise.resolve(2)
]
data
為 array,但其 element 都是 promise。
第 6 行
let f = arr => {
for (let x of arr)
console.log(x)
}
若想印出 array 中的值,直覺會使用 for
loop 搭配 console.log()
。
await
let data = [
Promise.resolve(1),
Promise.resolve(2)
]
let f = async arr => {
for (let x of arr)
console.log(await x)
}
f(data)
第 6 行
let f = async arr => {
for (let x of arr)
console.log(await x)
}
若要 console.log()
印出 promise 內部值,必須在每個 x
前加上 await
從 promise 取出。
for await of
let data = [
Promise.resolve(1),
Promise.resolve(2)
]
let f = async arr => {
for await(let x of arr)
console.log(x)
}
f(data)
ES2017 提供了 for await of
loop,如此 x
已經從 promise 中取出,console.log()
可直接使用。
Promise.all()
let data = [
Promise.resolve(1),
Promise.resolve(2)
]
let f = arr => Promise.all(arr)
.then(x => x.forEach(y => console.log(y)))
f(data)
若不想使用 async await
,對於 promise array 可先使用 Promise.all()
處理,如此 promise array 中的值會先從 promise 取出,唯 promise.all()
回傳為新的 promise,因此再使用 then()
解開才能搭配 forEach()
與 console.log()
印出。
Ramda
import { andThen, pipe, forEach } from 'ramda'
let data = [
Promise.resolve(1),
Promise.resolve(2)
]
let f = pipe(
x => Promise.all(x),
andThen(forEach(console.log))
)
f(data)
若使用 Ramda,則可善其 andThen()
與 forEach()
,整個流程以 pipe()
整合起來。
為 Ramda 並沒有提供 Promise.all()
的 function 版本,因此只能自行使用 arrow function。
Wink-fp
import { forEach } from 'ramda'
import { pipeP, all, resolve, log } from 'wink-fp'
let data = [
resolve(1),
resolve(2)
]
let f = pipeP(
all,
forEach(log)
)
f(data)
Wink-fp 提供了 Promise.all()
的 function 版本 all()
,可直接搭配 pipeP()
使用。
resolve()
則為 Promise.resolve()
的 function 版本。
all()
[Promise e a] -> Promise e b
Promise.all()
的 pure function 版本
[Promise e a]
:data 為 array promise
Promise e b
:已經 fulfilled promise,但包了一層新 promise
Conclusion
for await of
loop 比原本for of
loop 寫法優雅,且{}
可直接使用x
,不必再一直重複await
,但本質仍是 imperative- 若不喜歡使用
await
,promise array 可先用Promise.all()
處理,別忘了其回傳仍是 promise,因此必須接著使用then()
才能取得 promise 內部值 - 透過 Wink-fp 的
all()
,則Promise.all()
也能整合於pipeP()
中