我想反彈一個流 - 但僅當源值與以前相同時。我如何使用RxJS 5來做到這一點?RxJS:只有在不同的情況下才反彈一個流
我不想發出一個值,如果價值是相同的,我以前在指定的時間窗內發出它。我應該能夠使用流中的值 - 或者與distinctUntilChanged類似的比較函數。
我想反彈一個流 - 但僅當源值與以前相同時。我如何使用RxJS 5來做到這一點?RxJS:只有在不同的情況下才反彈一個流
我不想發出一個值,如果價值是相同的,我以前在指定的時間窗內發出它。我應該能夠使用流中的值 - 或者與distinctUntilChanged類似的比較函數。
我不知道有什麼辦法可以做到這一點,而不需要創建自己的操作符,因爲你需要維護某種狀態(最後一次看到的值)。
一種方法看起來是這樣的:
// I named this debounceDistinctUntilChanged but that might not be
// the best name. Name it whatever you think makes sense!
function debounceDistinctUntilChanged(delay) {
const source$ = this;
return new Observable(observer => {
// Using an object as the default value
// so that the first time we check it
// if its the same its guaranteed to be false
// because every object has a different identity.
// Can't use null or undefined because source may
// emit these!
let lastSeen = {};
return source$
.debounce(value => {
// If the last value has the same identity we'll
// actually debounce
if (value === lastSeen) {
return Observable.timer(delay);
} else {
lastSeen = value;
// This will complete() right away so we don't actually debounce/buffer
// it at all
return Observable.empty();
}
})
.subscribe(observer);
});
}
現在你看到一個實現你可能(也可能不會),發現它與你的期望不同。您的描述實際上忽略了某些細節,例如它應該只是在防抖時間框架內保留的最後值,或者如果它是一組 - 基本上distinctUntilChanged
與distinct
。我認爲後者。
無論哪種方式希望這給你一個出發點,並揭示了創建自定義運算符是多麼容易。內置的運營商絕對不會爲所有事情提供解決方案,因此任何足夠先進的應用程序都需要自己製作(或者在不抽象的情況下執行內聯命令,這也沒關係)。
Observable.prototype.debounceDistinctUntilChanged = debounceDistinctUntilChanged;
// later
source$
.debounceDistinctUntilChanged(400)
.subscribe(d => console.log(d));
或使用let
:
然後,您可以把它放在可觀察的原型使用該運營商
// later
source$
.let(source$ => debounceDistinctUntilChanged.call($source, 400))
.subscribe(d => console.log(d));
如果可以的話,我建議真正理解什麼是我的代碼確實如此,以便將來您可以輕鬆地制定自己的解決方案。
這是否回答了您的問題? :) – jayphelps
這取決於你想要做什麼;當我試圖做類似的事情時,我遇到了這個問題,基本上是去除了對象的不同值,但是具有不同的去抖動。
從jayphelps嘗試解決方案後,我無法讓它表現得如我所願。經過多次反覆,結果發現有一個簡單的方法可以實現它:groupby。
const priceUpdates = [
{bid: 10, id: 25},
{bid: 20, id: 30},
{bid: 11, id: 25},
{bid: 21, id: 30},
{bid: 25, id: 30}
];//emit each person
const source = Rx.Observable.from(priceUpdates);
//group by age
const example = source
.groupBy(bid => bid.id)
.mergeMap(group$ => group$.debounceTime(500))
const subscribe = example.subscribe(val => console.log(val));
輸出:
[object Object] {
bid: 11,
id: 25
}
[object Object] {
bid: 25,
id: 30
}
Jsbin:http://jsbin.com/savahivege/edit?js,console
此代碼將組由出價ID和反跳上,所以因此僅發送每個的最後的值。
「我應該能夠使用流中的值 - 或比較與distinctUntilChanged類似的函數。」這可能是你在說什麼,但[distinctUntilChanged(compare:function)'](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-distinctUntilChanged)允許你定義一個任意的比較器,你可以檢查排放之間的時間(甚至可以使用[時間戳](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-時間戳)運營商)。 – Whymarrh