我第一次嘗試使用反應式編程,使用bacon.js,並且發生了令我厭煩的奇怪的交互。我想出了這個事件鏈的工作版本,但是額外的流操作讓它從其他代碼中脫穎而出 - 如你所見。Observable.flatMapLatest:在更深層次取消?
我發現FRP/Bacon.js生成一些非常乾淨的代碼,所以感覺就像我只是缺少一些明顯的操作符。對於這個問題,我們呢?
多個來源建議使用Observable.flatMapLatest
來放棄陳舊事件。假設我們要爲輸入流中的每個事件完成IO操作。在下圖中,i
代表輸入流事件,rN
代表每個請求流的事件,並且x
ES標記請求流被取消時的時間點。這些很可能是單事件流,所以.
意味着事件之後流實際上是關閉的(如果它之前未被取消!)。
input stream: i──i────────i───i─────────>
request: │ │ │ └────r4.──>
request: │ │ └───x─r3.─────>
request: │ └──r2.───x─────────────>
request: └──x─────r1.──────────────>
+
i.flatMapLatest(requests): ──────r2─────────────r4───>
這是幾個用例完全沒有問題,但要注意r3
:它永遠不會被接受,儘管它仍然是一個有效的響應,直到r4
到來。在最壞的情況下,大量的請求都被浪費掉:
input stream: i──i──i───i──i──────>
request: │ │ │ └──x─r4.──>
request: │ │ └───x─r3.─────>
request: │ └──x─r2.─────────>
request: └──x─────r1.────────>
+
i.flatMapLatest(requests): ────────────────────>
我知道我們可以用throttle
和debounce
處理這類情況,但他們仍然容易受到(大)時序問題。例如,一個點狀連接的用戶(其請求需要0.5s-5s +)可能會受到這個嚴重影響。
現在,即使這不是一個真正的問題,它看起來對我的玻璃鋼研究很有價值。如果它是不明確的,現在,這就是我想做的事:
input stream: i──i────────i───i─────────>
request: │ │ │ └────r4.──>
request: │ │ └─────r3.─x───>
request: │ └──r2.──────────x──────>
request: └──────x─r1.──────────────>
+
i.flatMap_What?(requests): ──────r2──────────r3─r4───>
而且這裏是我當前的實現與基本flatMapLatest
一個:
var wrong = function (interval, max_duration) {
var last_id = 0,
interval = interval || 1000,
max_duration = max_duration || 5000;
Bacon.interval(interval, 'bang').log('interval:')
.flatMapLatest(function() {
return Bacon.later(Math.random()*max_duration, last_id++).log(' request:');
})
.log('accepted: %s **********');
};
var right = function (interval, max_duration) {
var last_id = 0,
interval = interval || 1000,
max_duration = max_duration || 5000;
Bacon.interval(interval, 'bang').log('interval:')
.flatMap(function() {
return Bacon.later(Math.random()*max_duration, last_id++).log(' request:');
})
.diff(-1, function (a, b) { return b > a ? b : -1 })
.filter(function (id) { return id !== -1 })
.log('accepted: %s **********');
};
的wrong
函數忽略連續請求符合預期,而right
功能在普通flatMap
上運行,其中diff
和filter
。但不僅如此,它看起來很詭異,它將時間戳/ ID添加爲請求的要求,只是以後我們可以對其進行排序。
我想我的問題是,那麼:我錯過了什麼?有一個更好的方法嗎?我怎樣才能takeUntil
每個flatMap
事件流(請求),而不是外部的一個(輸入)?
任何幫助表示讚賞,謝謝!
我想大部分的時間'flatMapLatest'是做你想要什麼:如果輸入已經改變,結果以前的請求無效。一個簡單的例子就是搜索字段文本和相應的搜索結果。 – OlliM
在你的例子中,你應該使用'scan'而不是diff來維護已經通過的最大id:如果結果按[r3,r1,r2]順序排列,那麼錯誤的事情將會通過。 – OlliM