除了可以由 RxJS 的 Operator 建立 Observable 外,我們也可使用 map()
從既有 Observable 繼續建立新 Observable。
Version
macOS Catalina 10.15.4
WebStorm 2020.1
Vue 2.6.11
RxJS 6.5.5
Browser
由一個 Observable 再分別建立兩個 Observable 顯示。
subscriptions()
<template>
<div>
<h1>{{ interval1$ }}</h1>
<h1>{{ interval2$ }}</h1>
</div>
</template>
<script>
import { interval } from 'rxjs'
import { map } from 'rxjs/operators'
let subscriptions = _ => {
let interval$ = interval(1000)
let interval1$ = interval$.pipe(map(x => x * 2))
let interval2$ = interval$.pipe(map(x => x * 3))
return { interval1$, interval2$ }
}
export default {
name: 'app',
subscriptions,
}
</script>
13 行
let interval$ = interval(1000)
let interval1$ = interval$.pipe(map(x => x * 2))
let interval2$ = interval$.pipe(map(x => x * 3))
由於 subscriptions
本質是 function,因此我們可以在 subscriptions()
直接建立 interval$
observable,除此之外,還可以由 map()
建立新的 Observable。
map()
由 Observable 根據傳入 function 運算成新 Observable
Point-free
<template>
<div>
<h1>{{ interval1$ }}</h1>
<h1>{{ interval2$ }}</h1>
</div>
</template>
<script>
import { interval } from 'rxjs'
import { map } from 'rxjs/operators'
import { multiply } from 'ramda'
let subscriptions = _ => {
let interval$ = interval(1000)
let interval1$ = interval$.pipe(map(multiply(2)))
let interval2$ = interval$.pipe(map(multiply(3)))
return { interval1$, interval2$ }
}
export default {
name: 'app',
subscriptions,
}
</script>
15 行
let interval1$ = interval$.pipe(map(multiply(2)))
let interval2$ = interval$.pipe(map(multiply(3)))
map()
的 callback 可進一步使用 Ramda 的 multiply()
加以 point-free。
Function Composition
<template>
<div>
<h1>{{ interval1$ }}</h1>
<h1>{{ interval2$ }}</h1>
</div>
</template>
<script>
import { interval, pipe } from 'rxjs'
import { map } from 'rxjs/operators'
import { multiply } from 'ramda'
let mul = pipe(multiply, map)
let subscriptions = _ => {
let interval$ = interval(1000)
let interval1$ = interval$.pipe(mul(2))
let interval2$ = interval$.pipe(mul(3))
return { interval1$, interval2$ }
}
export default {
name: 'app',
subscriptions,
}
</script>
13 行
let mul = pipe(multiply, map)
我們發現兩個 pipe()
內都是 map(multiply(x))
,這是重複的部分,而這正是 f(g(x))
形式,也就是 Function Composition,因此可用 RxJS 的 pipe()
將 multiply()
與 map()
加以組合。
17 行
let interval1$ = interval$.pipe(mul(2))
let interval2$ = interval$.pipe(mul(3))
pipe()
就能使用新組合的 mul()
,語意更清楚。
Conclusion
- 可使用
map()
將既有 Observable 依照 function 規則建立新 Observable - RxJS 的
pipe()
會組合眾多 operator,由於都是 pure function,可輕易使用pipe()
加以組合,實現 Function Composition
Reference
John Lindquist, Create RxJS Streams in the Vue.js Subscriptions Function
RxJS, map()