這節(jié)講非常重要同時非常容易混淆的合并操作符凛膏,從名字上次都是合并,但是區(qū)別還是蠻大的,我會盡量結合Marble Diagram(彈珠圖)解釋清楚。
concat
首先登場的是concat阶捆,用來連接多個 observable。并順序依次執(zhí)行
特點:按照順序钦听,前一個 observable 完成了再訂閱下一個 observable 并發(fā)出值
注意事項:此操作符可以既有靜態(tài)方法洒试,又有實例方法
Marble Diagram:
source : ----0----1----2|
source2: (3)|
source3: (456)|
concat()
example: ----0----1----2(3456)|
例子:
const { concat } = rxjs.operators;
const { of } = rxjs;
const sourceOne = of(1, 2, 3);
const sourceTwo = of(4, 5, 6);
const sourceThree = of(7, 8);
// 先發(fā)出 sourceOne 的值,當完成時訂閱 sourceTwo
// 輸出: 1,2,3,4,5,6,7,8
// 特點: 必須先等前一個 observable 完成(complete)朴上,才會繼續(xù)下一個
sourceOne
.pipe(
concat(sourceTwo, sourceThree)
)
.subscribe(val =>
console.log('Example: Basic concat:', val)
);
// 等價寫法垒棋, 把 concat 作為靜態(tài)方法使用,這樣更直觀
rxjs
.concat(sourceOne, sourceTwo)
.subscribe(val =>
console.log(val)
);
merge
特點:merge 把多個 observable 同時處理痪宰,這跟 concat 一次處理一個 observable 是完全不一樣的叼架,由于是同時處理行為會變得較為復雜。
merge 的邏輯有點像是 OR(||)衣撬,就是當兩個 observable 其中一個被觸發(fā)時都可以被處理乖订,這很常用在一個以上的按鈕具有部分相同的行為。
同樣 既有靜態(tài)方法具练,又有實例方法
rxjs
.merge(
interval(500).pipe(take(3)),
interval(300).pipe(take(6)),
)
.subscribe(val =>
console.log(val)
);
sourceOne
.pipe(
merge(sourceTwo)
)
.subscribe(val =>
console.log(val)
);
Marble Diagram:
source : ----0----1----2|
source2: --0--1--2--3--4--5|
merge()
example: --0-01--21-3--(24)--5|
例如一個影片播放器有兩個按鈕乍构,一個是暫停(II),另一個是結束播放(口)靠粪。這兩個按鈕都具有相同的行為就是影片會被停止蜡吧,只是結束播放會讓影片回到 00 秒毫蚓,這時我們就可以把這兩個按鈕的事件 merge 起來處理影片暫停這件事。
var stopVideo = rxjs.merge(stopButton, endButton);
stopVideo.subscribe(() => {
// 暫停播放影片
})
concatAll
有時我們的 Observable 送出的元素又是一個 observable昔善,就像是二維數(shù)組元潘,數(shù)組里面的元素是數(shù)組,這時我們就可以用 concatAll 把它攤平成一維數(shù)組君仆,大家也可以直接把 concatAll 想成把所有元素 concat 起來翩概。
特點:攤平 Observable
// 我們每點擊一次 body 就會立刻送出 1,2,3
fromEvent(document.body, 'click')
.pipe(
// 內部發(fā)出值是 observable 類型
map(e => of(1,2,3)),
// 取 observable 的值
concatAll(),
)
.subscribe(val =>
console.log(val)
);