2017-06-14 83 views
3

我想反彈一個流 - 但僅當源值與以前相同時。我如何使用RxJS 5來做到這一點?RxJS:只有在不同的情況下才反彈一個流

我不想發出一個值,如果價值是相同的,我以前在指定的時間窗內發出它。我應該能夠使用流中的值 - 或者與distinctUntilChanged類似的比較函數。

+0

「我應該能夠使用流中的值 - 或比較與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

回答

1

我不知道有什麼辦法可以做到這一點,而不需要創建自己的操作符,因爲你需要維護某種狀態(最後一次看到的值)。

一種方法看起來是這樣的:

// 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); 
    }); 
} 

現在你看到一個實現你可能(也可能不會),發現它與你的期望不同。您的描述實際上忽略了某些細節,例如它應該只是在防抖時間框架內保留的最後值,或者如果它是一組 - 基本上distinctUntilChangeddistinct。我認爲後者。

無論哪種方式希望這給你一個出發點,並揭示了創建自定義運算符是多麼容易。內置的運營商絕對不會爲所有事情提供解決方案,因此任何足夠先進的應用程序都需要自己製作(或者在不抽象的情況下執行內聯命令,這也沒關係)。

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)); 

如果可以的話,我建議真正理解什麼是我的代碼確實如此,以便將來您可以輕鬆地制定自己的解決方案。

+0

這是否回答了您的問題? :) – jayphelps

1

這取決於你想要做什麼;當我試圖做類似的事情時,我遇到了這個問題,基本上是去除了對象的不同值,但是具有不同的去抖動。

從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和反跳上,所以因此僅發送每個的最後的值。

相關問題