RxJS 與 Ramda 皆可無痛整合在 Vue

RxJS 與 Ramda 同屬 Functional Library,RxJS 特色在於 Asynchronous 部分,而 Ramda 則在於 Synchronous 部分,事實上 RxJS 與 Ramda 可以搭配一起在 Vue 使用。

Version

Vue 2.6.6
Vue-rx 6.1.0
RxJS 6.4.0
Ramda 0.26.1

RxJS


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
<div>
<h1>{{ interval1$ }}</h1>
<h1>{{ interval2$ }}</h1>
</div>
</template>

<script>
import { interval } from 'rxjs'
import { map } from 'rxjs/operators'

const interval$ = interval(1000)
const interval1$ = interval$.pipe(map(x => x * 2))
const interval2$ = interval$.pipe(map(x => x * 3))

export default {
name: 'app',
subscriptions: () => ({
interval1$,
interval2$
})
}
</script>

18 行

1
2
3
4
subscriptions: () => ({
interval1$,
interval2$
})

subscriptionsdata 一樣,本質是 function,將所有的 Observable 宣告在 subscriptions() 的 return object。

1
2
3
const interval$ = interval(1000)
const interval1$ = interval$.pipe(map(x => x * 2))
const interval2$ = interval$.pipe(map(x => x * 3))

定義 interval$ Observable,由於並不需要顯示在 HTML Template 內,因此不需要定義在 subscriptions 內。

實務上並不需要所有 Observable 都宣告在 subscriptions 內,只有需要做 Data Binding 的 Observable 才要在 subscriptions 內宣告

interval$ 定義 interval1$interval2$,使用 RxJS 的 map() operator 重新定義 Observable。

RxJS 如同 Ramda 一樣,其 operator 要包在 pipe() 內。

目前為止一切順利,唯 map() 的 callback 並非 Point-free,有辦法繼續改善嗎 ?

Ramda


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
<div>
<h1>{{ interval1$ }}</h1>
<h1>{{ interval2$ }}</h1>
</div>
</template>

<script>
import { interval } from 'rxjs'
import { map } from 'rxjs/operators'
import { multiply } from 'ramda'

const interval$ = interval(1000)
const interval1$ = interval$.pipe(map(multiply(2)))
const interval2$ = interval$.pipe(map(multiply(3)))

export default {
name: 'app',
subscriptions: () => ({
interval1$,
interval2$
})
}
</script>

13 行

1
2
3
const interval$ = interval(1000)
const interval1$ = interval$.pipe(map(multiply(2)))
const interval2$ = interval$.pipe(map(multiply(3)))

引進了 Ramda 的 multiply() operator,如此 map() 也 Point-free 了。

Conclusion


  • RxJS 與 Ramda 雖然分屬兩個不同的 library,但彼此可以相互搭配,使 RxJS 也能 Point-free
  • 由於 Vue 的 computedmethodsubscriptions 本質都是 function,因此可以使用 RxJS 與 Ramda 產生,充分發揮 FP 的 Function Composition

Sample Code


完整範例可以在我 GitHub 上找到

2019-02-22