RxJS 與 Ramda 同屬 Functional Library,RxJS 特色在於 Asynchronous 部分,而 Ramda 則在於 Synchronous,事實上 RxJS 與 Ramda 可搭配 Vue 一起使用。
Version
macOS Catalina 10.15.4
VS Code 1.44.3
Quokka 1.0.287
RxJS 7.0.0
Ramda 0.27.0
Vue 2.6.11
RxJS
import { interval } from 'rxjs'
import { map } from 'rxjs/operators'
interval(1000)
.pipe(map(x => x * 2))
.subscribe(x => console.log(x))
由 interval()
每秒建立 Observable,想透過 map()
將其乘以 2
,最後 console.log()
印出。
Ramda
import { interval } from 'rxjs'
import { map } from 'rxjs/operators'
import { multiply } from 'ramda'
import { log } from 'wink-fp'
interval(1000)
.pipe(map(multiply(2)))
.subscribe(log)
雖然 RxJS 是 asynchronous,但 operator 的 callback 則是 synchronous,因此這部分可使用 Ramda。
x => x * 2
改用 Ramda 的multiply(2)
產生x => console.log(x)
改用 Wink-fp 的log()
產生
Function Composition
import { interval } from 'rxjs'
import { map } from 'rxjs/operators'
import { multiply, compose } from 'ramda'
import { log } from 'wink-fp'
let calculate = compose(map, multiply)
interval(1000)
.pipe(calculate(2))
.subscribe(log)
RxJS 的 callback 常會看到類似 map(multiply(2))
形式,這是典型的 f(g(x))
,也就是 Function Composition,可使用 Ramda 的 compose()
加以組合。
Vue-rx
<template>
<div>
<h1>{{ stream$ }}</h1>
</div>
</template>
<script>
import { interval } from 'rxjs'
import { map } from 'rxjs/operators'
import { multiply, compose } from 'ramda'
let calculate = compose(map, multiply)
let subscriptions = _ => {
let stream$ = interval(1000).pipe(
calculate(2)
)
return { stream$ }
}
export default {
name: 'app',
subscriptions
}
</script>
14 行
let subscriptions = _ => {
let stream$ = interval(1000).pipe(
calculate(2)
)
return { stream$ }
}
subscriptions
如 data
一樣,本質是 function,將所有 Observable 處理與宣告都在 subscriptions()
內。
15 行
let stream$ = interval(1000).pipe(
calculate(2)
)
定義 stream$
Observable,由 RxJS 的 interval()
搭配 pipe()
產生。
12 行
let calculate = compose(map, multiply)
一樣使用 Ramda 的 compose()
組合 map()
與 multiply()
。
Conclusion
- RxJS 與 Ramda 雖然分屬兩個不同的 library,但彼此可以相互搭配,使 RxJS 也能 享受 point-free 與 Function Composition