書接上文,我們知道只要打開定時器,控制臺就會一直輸出內(nèi)容≡我ぃ現(xiàn)在我們提出個小需求,只有在文本框輸入的內(nèi)容和定時器的值相等時才輸出卵佛。用 map 操作符當然可以實現(xiàn)杨赤,但最佳實踐是使用 filter 操作符。
filter:輸入?yún)?shù)為一個條件函數(shù)截汪,也就是返回布爾值的函數(shù)疾牲。意思是對原數(shù)據(jù)流中的數(shù)據(jù)進行判斷,符合條件的才傳遞給下面的操作符衙解。
那我們的需求很容易就可以完成了:
combineLatest(
timer$,
input$,
(timeValue, inputValue) => ({count: timeValue, input: inputValue})
)
.pipe(
filter(data => data.count === parseInt(data.input)),
tap(console.log)
).subscribe()
比如我們在輸入框輸入 3 阳柔,再打開定時器,控制臺沒有任何輸出蚓峦;當定時器到達 3 時舌剂,控制臺才會輸出济锄。
我們知道當一個流完成時會觸發(fā) complete 事件,然而 filter 操作符并不會觸發(fā)上游數(shù)據(jù)流的 complete 事件霍转,它只是個閥門荐绝,滿足它條件的數(shù)據(jù)才會放過。如果想滿足條件后出發(fā)上游數(shù)據(jù)流的 complete 事件避消,filter 的兄弟 takeWhile 可以幫你完成低滩。
takeWhile:輸入?yún)?shù)和 filter 一樣, 為一條件函數(shù)岩喷,返回布爾值恕沫,當接收到的數(shù)據(jù)滿足條件函數(shù)才會輸出,只要不滿足就馬上觸發(fā)上游數(shù)據(jù)流的 complete 事件纱意。
實例最能讓你體會到這個操作符的行為婶溯。代碼很簡單,就是把 filter 操作符換成 takeWhile 操作符:
combineLatest(
timer$,
input$,
(timeValue, inputValue) => ({count: timeValue, input: inputValue})
)
.pipe(
takeWhile(data => data.count === parseInt(data.input)),
tap(console.log)
)
.subscribe()
效果圖:
一開始是沒有輸出的妇穴,因為 combineLatest 要等兩個流都有值才能輸出爬虱,定時器有初始值 0 , 文本框沒有值腾它。當我們在文本框中輸入 0 時,控制臺輸出了死讹,這是因為 combineLatest 產(chǎn)生的對象滿足 takeWhile 的條件函數(shù)瞒滴。但當定時器變?yōu)?1 時,馬上就停止了赞警。這是因為妓忍,combineLatest 產(chǎn)生的第二個值不滿足 takeWhile 的條件函數(shù),根據(jù)定義愧旦,馬上觸發(fā) combineLatest 的 complete 事件世剖,也就是結(jié)束數(shù)據(jù)流,不再有數(shù)據(jù)產(chǎn)生笤虫。
我們在 subscribe 函數(shù)中加入完整的回調(diào)函數(shù)旁瘫,看下是否真的觸發(fā)了 complete 事件:
combineLatest(
timer$,
input$,
(timeValue, inputValue) => ({ count: timeValue, input: inputValue })
)
.pipe(
takeWhile(data => data.count === parseInt(data.input)),
tap(console.log)
)
.subscribe(
_ => console.log("next"),
e => console.log("error"),
() => console.log("complete")
)
效果圖:
如有任何問題,請?zhí)砑游⑿殴娞枴白x一讀我”琼蚯。