Side Effect 在實務上不可避免,若同時要對相同 Value 執行多次 Side Effect 時,標準做法是使用 tap()
,可使用 seq()
更精簡。
Version
Wink-fp 1.23.9
tap()
import { pipe, inc, tap } from 'ramda'
let result1 = 0
let result2 = 0
let effectResult1 = x => result1 = x
let effectResult2 = pipe(
inc,
x => result2 = x
)
pipe(
inc,
tap(effectResult1),
tap(effectResult2)
)(1)
result1 // ?
result2 // ?
第 3 行
let result1 = 0
let result2 = 0
第 6 行
let effectResult1 = x => result1 = x
第一個 effectResult()
寫入 result1
side effect。
第 8 行
let effectResult2 = pipe(
inc,
x => result2 = x
)
先執行 inc()
後再寫入 result2
side effect。
13 行
pipe(
inc,
tap(effectResult1),
tap(effectResult2)
)(1)
標準做法是使用兩次 tap()
寫入兩個 side effect。
seq()
import { pipe, inc, forEach } from 'ramda'
let result1 = 0
let result2 = 0
let effectResult1 = x => result1 = x
let effectResult2 = pipe(
inc,
x => result2 = x
)
let seq = (...fs) => x => (forEach(f => f(x), fs), x)
pipe(
inc,
seq(effectResult1, effectResult2)
)(1)
result1 // ?
result2 // ?
13 行
let seq = (...fs) => x => (forEach(f => f(x), fs), x)
seq()
為 variadic function,可接受多個 function 為 argument,因為在 ES6 的 rest parameter 就是 Array,因此可直接使用 forEach()
執行多個 side effect。
最後將 x
回傳使 Function Pipeline 不中斷。
15 行
pipe(
inc,
seq(effectResult1, effectResult2)
)(1)
使用 seq()
取代 tap()
只要一行即可。
Wink-fp
import { pipe, inc } from 'ramda'
import { seq } from 'wink-fp'
let result1 = 0
let result2 = 0
let effectResult1 = x => result1 = x
let effectResult2 = pipe(
inc,
x => result2 = x
)
pipe(
inc,
seq(effectResult1, effectResult2)
)(1)
result1 // ?
result2 // ?
Wink-fp 已經內建 seq()
可直接使用。
seq()
((a -> *),...) -> a -> a
同時執行多個 side effect
((a -> *),...)
:可傳入多的 function 執行 side effect
a
:除入任何型別資料
a
:回傳該資料以利繼續 Function Pipeline
Conclusion
seq()
也稱為 S Combinator,在 Function Pipeline 中同時執行多個 Side Effect 時特別好用