實務上我們可能累積了很多 Synchronous Function,但現在想轉成 Asynchronous Function 改回傳 Promise,這種常見的需求該如何實現呢 ?
Version
macOS Catalina 10.15.6
VS Code 1.47.3
Quokka 1.0.312
Wink-fp 1.20.71
Async
let f = async x => x + 1
f(1) // ?
在 arrow function 前加上 ES2017 的 async
之後,inc()
搖身一變成為 asynchronous function,改回傳 Promise。
Promise.resolve()
let f = x => Promise.resolve(x + 1)
f(1) // ?
async
算 syntatic sugar,實際上使用 Promise.resolve()
將 x + 1
回傳值轉成 Promise。
Ramda
import { pipe, inc, bind } from 'ramda'
let resolve = bind(Promise.resolve, Promise)
let f = pipe(
inc,
resolve
)
f(1) // ?
由以上範例可發現,實際上是先經過 x => x + 1
的運算,再將結果傳給 Promise.resolve()
轉成 Promise
,這是一個 pipeline 過程。
且 x => x + 1
是很普通的 synchronous function,如 Ramda 早已提供 inc()
,可直接使用。
既然 Ramda 有提供 inc()
,又有 pipeline 本質,獨缺 resolve()
就可 pipeline,我們可自行建立使用 bind()
將 Promise.resolve()
static method 轉成 resolve()
free function,如此就能使用 pipe()
將 inc()
與 resolve()
串起來。
Wink-fp
import { pipe, inc } from 'ramda'
import { resolve } from 'wink-fp'
let f = pipe(
inc,
resolve
)
f(1) // ?
Wink-fp 已經提供 resolve()
,可直接使用。
resolve()
a -> Promise a
將任意值包成 Fulfilled Promise
a
:data 為任意值
Promise a
:包成 Promise 回傳
Conclusion
- ECMAScript 很多 API 可能不適合 Function Pipeline,但我們可以使用
invoker()
與bind()
包成 free function - 透過 function 化的
resolve()
,我們就可組合既有的 synchronous function 產生 asynchronous function