30日間RxJS(15):Observable Operators-distinct,distinctUntilChangedに精通
4628 ワード
昨日私たちはthrottleとdebounceの2つの方法を話して効率の最適化をしましたが、実はもう1つの方法が効率の最適化処理をすることができます.それはdistinctです.
Operators
distinct
SQL命令を下すのはすべてdistinctに対してよく知らないべきで、それは私达に同じ値の资料をフィルタリングして1笔だけ残すことができて、RxJSの中のdistinctも同じ作用で、私达に直接例を见てみましょう
JSBin | JSFiddle
Marble Diagramで表すと次のようになります.
上記の例から分かるように,distinctを用いると,重複する値がある限りフィルタリングされる.
また、selector callback functionを入力することができます.このcallback functionは、受信した要素を入力し、私たちが本当に比較したい値を返します.例えば、次のようにします.
JSBin | JSFiddle
ここでは、sourceが送り出すのはすべて物であり、js物の対比は比較記憶体の位置であるため、この例ではこれらの物は永遠に等しくないが、実際には比較したいのは物の中のvalueであり、このときselector callbackに転送して、私たちが比較する値を選択することができる.
distinctから届いたcallbackはRxJS 5のいくつかのbateバージョンで多くの変更がありました.今、ネット上の多くの文章と教育は時代遅れです.読者は気をつけてください.
実際には
ここでいうSetは実はRxJS自身が実作したもので,ES 6原生のSet行為とも一致しているが,ES 6のSet支援の程度がまだ理想的ではないため,ここでは直接JS実作を用いる.
distinctは、2番目のパラメータflushes observableを入力して、一時保存された資料を消去することができます.例は次のとおりです.
JSBin | JSFiddle
ここではMarble Diagramの方が表現しやすいです
実はflushes observableは要素を送り出す時、distinctの一時保存をクリアするので、その後の一時保存は最初からやり直すので、一時保存のSetがますます大きくなる問題を心配する必要はありませんが、実は私たちは普段このような方法で処理することはあまりなく、通常は別の方法でdistinctUntilChangedを使用します.
distinctUntilChanged
distinctUntilChangedはdistinctと同じように同じ要素をフィルタリングしますが、distinctUntilChangedは最後に送信された要素と比較するだけで、どれも比べられません.例えば、次のようになります.
JSBin | JSFiddle
ここでdistinctUntilChangedは1つの要素しか一時的に保存されず、要素を受信したときに一時的に保存された要素と比較し、同じであれば送信されず、異なる場合は一時的に保存された要素を受信したばかりの新しい要素に変換して送信します.
Marble Diagramでは、2番目のcが送り出されたときにちょうど1つ上がcだったのでフィルタリングされたが、最後のbは1つと異なるのでフィルタリングされなかった.
distinctUntilChangedは実務的によく使われていますが、最も一般的な状況は私たちが多角的な同期をしているときです.複数のClientがあり、各Clientがそれぞれのステータスを持っている場合、Serverはもう1つのClientが変更する必要がある場合、すべてのClient更新を通知しますが、いくつかのClientが新しいステータスを受信した場合、実際には前回受信したのと同じである可能性があります.この場合、distinctUntilChangedメソッドを使用して、最後のメッセージとは異なるメッセージのみを処理できます.例えば、マルチ通話、マルチデバイスの情報同期には似たような状況があります.
今日のまとめ
今日は2つのdistinct方法について話しましたが、この2つの方法は普段はあまり使えないかもしれませんが、複雑なアプリケーションを必要とする上で欠かせない良い方法で、特に多くの人がすぐに同期する状況を処理するには、これは非常に使いやすい方法で、読者たちは今日収穫があるかどうか分かりません.もし何か問題があったら、下にメッセージを残してください.ありがとうございます.
Operators
distinct
SQL命令を下すのはすべてdistinctに対してよく知らないべきで、それは私达に同じ値の资料をフィルタリングして1笔だけ残すことができて、RxJSの中のdistinctも同じ作用で、私达に直接例を见てみましょう
var source = Rx.Observable.from(['a', 'b', 'c', 'a', 'b'])
.zip(Rx.Observable.interval(300), (x, y) => x);
var example = source.distinct()
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// a
// b
// c
// complete
JSBin | JSFiddle
Marble Diagramで表すと次のようになります.
source : --a--b--c--a--b|
distinct()
example: --a--b--c------|
上記の例から分かるように,distinctを用いると,重複する値がある限りフィルタリングされる.
また、selector callback functionを入力することができます.このcallback functionは、受信した要素を入力し、私たちが本当に比較したい値を返します.例えば、次のようにします.
var source = Rx.Observable.from([{ value: 'a'}, { value: 'b' }, { value: 'c' }, { value: 'a' }, { value: 'c' }])
.zip(Rx.Observable.interval(300), (x, y) => x);
var example = source.distinct((x) => {
return x.value
});
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// {value: "a"}
// {value: "b"}
// {value: "c"}
// complete
JSBin | JSFiddle
ここでは、sourceが送り出すのはすべて物であり、js物の対比は比較記憶体の位置であるため、この例ではこれらの物は永遠に等しくないが、実際には比較したいのは物の中のvalueであり、このときselector callbackに転送して、私たちが比較する値を選択することができる.
distinctから届いたcallbackはRxJS 5のいくつかのbateバージョンで多くの変更がありました.今、ネット上の多くの文章と教育は時代遅れです.読者は気をつけてください.
実際には
distinct()
はバックグラウンドにSetを確立し,要素を受信するとまずSet内に同じ値があるかどうかを判断し,ある場合は送出せず,ない場合はSetに格納して送出する.だから、できるだけdistinctを無限のobservableに直接使用しないでください.そうすると、Setがますます大きくなる可能性があります.2番目のパラメータflushesを置くか、distinctUntilChangedを使うことをお勧めします.ここでいうSetは実はRxJS自身が実作したもので,ES 6原生のSet行為とも一致しているが,ES 6のSet支援の程度がまだ理想的ではないため,ここでは直接JS実作を用いる.
distinctは、2番目のパラメータflushes observableを入力して、一時保存された資料を消去することができます.例は次のとおりです.
var source = Rx.Observable.from(['a', 'b', 'c', 'a', 'c'])
.zip(Rx.Observable.interval(300), (x, y) => x);
var flushes = Rx.Observable.interval(1300);
var example = source.distinct(null, flushes);
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// a
// b
// c
// c
// complete
JSBin | JSFiddle
ここではMarble Diagramの方が表現しやすいです
source : --a--b--c--a--c|
flushes: ------------0---...
distinct(null, flushes);
example: --a--b--c-----c|
実はflushes observableは要素を送り出す時、distinctの一時保存をクリアするので、その後の一時保存は最初からやり直すので、一時保存のSetがますます大きくなる問題を心配する必要はありませんが、実は私たちは普段このような方法で処理することはあまりなく、通常は別の方法でdistinctUntilChangedを使用します.
distinctUntilChanged
distinctUntilChangedはdistinctと同じように同じ要素をフィルタリングしますが、distinctUntilChangedは最後に送信された要素と比較するだけで、どれも比べられません.例えば、次のようになります.
var source = Rx.Observable.from(['a', 'b', 'c', 'c', 'b'])
.zip(Rx.Observable.interval(300), (x, y) => x);
var example = source.distinctUntilChanged()
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// a
// b
// c
// b
// complete
JSBin | JSFiddle
ここでdistinctUntilChangedは1つの要素しか一時的に保存されず、要素を受信したときに一時的に保存された要素と比較し、同じであれば送信されず、異なる場合は一時的に保存された要素を受信したばかりの新しい要素に変換して送信します.
source : --a--b--c--c--b|
distinctUntilChanged()
example: --a--b--c-----b|
Marble Diagramでは、2番目のcが送り出されたときにちょうど1つ上がcだったのでフィルタリングされたが、最後のbは1つと異なるのでフィルタリングされなかった.
distinctUntilChangedは実務的によく使われていますが、最も一般的な状況は私たちが多角的な同期をしているときです.複数のClientがあり、各Clientがそれぞれのステータスを持っている場合、Serverはもう1つのClientが変更する必要がある場合、すべてのClient更新を通知しますが、いくつかのClientが新しいステータスを受信した場合、実際には前回受信したのと同じである可能性があります.この場合、distinctUntilChangedメソッドを使用して、最後のメッセージとは異なるメッセージのみを処理できます.例えば、マルチ通話、マルチデバイスの情報同期には似たような状況があります.
今日のまとめ
今日は2つのdistinct方法について話しましたが、この2つの方法は普段はあまり使えないかもしれませんが、複雑なアプリケーションを必要とする上で欠かせない良い方法で、特に多くの人がすぐに同期する状況を処理するには、これは非常に使いやすい方法で、読者たちは今日収穫があるかどうか分かりません.もし何か問題があったら、下にメッセージを残してください.ありがとうございます.