RxJSの書き込み-DOMイベント編


RxJSの新しい悩み第1弾では、使用活動のメリットを考えてみましょう.
RxJSの公式文書Overviewでは、次のような傍観者の章節を参照します.
As opposed to EventEmitters which share the side effects and have eager execution regardless of the existence of subscribers, Observables have no shared execution and are lazy.
分析すると、EventEmitterは、Subscriberの存在にかかわらず、エッジ性能を共有しながら熱心に実行され、Observableは不活性に実行され、エッジ性能は共有されないと言える.
その言葉では、Observableはサイド機能を共有しないので、メンテナンス可能なイベントハンドルが使えると思います.これを証明するために、DOM Event環境でEventEmitterを書き込む方法と、RxJSでObservableを書き込む方法の2つの例を挙げて説明します.
結論として、コードメンテナンスにおいても優れています.

EventEmitterの例

let count = 0;
let rate = 1000;
let lastEvent = Date.now() - rate;
document.addEventListener('click', () => {
  if (Date.now() - lastEvent >= rate) {
    console.log(`Clicked ${++count} times`);
    lastEvent = Date.now();
  }
});
EventEmitterではありませんが、DOM APIのaddEventListenerも同様の役割を果たしているので、DOM APIの例を挙げます.
これは、イベントが少なくとも1秒間隔で実行されることを保証するために、毎秒単位でスロットルされるコードです.
イベントSubscriberは、複数のモジュールに共有されるグローバル変数を変更しています.関連変数をSubscriberに含めると、各Subscriberの実行時に変数が初期化され、Throttleの目的に反する結果になります.
  • 緊急実行は、イベントに登録されたSubscriberを巡回するemitメソッド自体の演算である.
  • 」という言葉自体に深い意味はありません.これはObservableと比較するためですが、「Subscriberに何があるのか気にしないで、イベントを出すだけです.登録されたイベントがあれば、ありがとう?いいえ」と簡単に言います.これは関心のあるニュアンスの違いにすぎない.コードの例が必要な場合は、Node EventEmitterの説明の下部を参照してください.△この文章の後半を読んだら、理解できます.
  • これらの論理を他のイベントに再使用する場合は、次のように問題が発生します.
    let count = 0;
    let rate = 1000;
    let lastEvent = Date.now() - rate;
    
    function countWithTrottle() {
      if (Date.now() - lastEvent >= rate) {
        console.log(`Clicked ${++count} times`);
        lastEvent = Date.now();
      }
    }
    
    document.addEventListener('click', countWithTrottle);
    document.addEventListener('keypress', countWithThrottle);
    
    結果は明らかだ.LastEvent変数とcount変数が共有され、不合理な結果が生成されます.
    この問題を解決するには、EventEmitterを使用する場合、サイドローブを隔離するためにエンクロージャを使用する必要がある場合があります.
    function getThrottleCounter(rate) {
      let count = 0;
      let lastEvent = Date.now() - rate;
      
      return function () {
        if (Date.now() - lastEvent >= rate) {
          console.log(`Clicked ${++count} times`);
          lastEvent = Date.now();
        }
      }
    }
    
    document.addEventListener('click', getThrottleCounter(1000));
    document.addEventListener('keypress', getThrottleCounter(1000));
    コンテキスト分離を実行するため、サイドエフェクトは共有されません.ただし、関数を呼び出すたびにメモリに同じ関数がロードされます.これは効率が悪いだけでなく、コードも直感的ではありません.
    RxJSがこれらの問題をどのように解決しているかを見てみましょう.

    RxJS Observableの例

    fromEvent(document, 'click')
      .pipe(
        throttleTime(1000),
        scan(count => count + 1, 0)
      )
      .subscribe(count => console.log(`Clicked ${count} times`));
    
    fromEvent(document, 'keypress')
      .pipe(
        throttleTime(1000),
        scan(count => count + 1, 0)
      )
      .subscribe(count => console.log(`Clicked ${count} times`));
    throttleTime演算子を使用すると、throttleの実装が簡略化されるだけでなく、スキャン演算子を使用して独自の状態がカプセル化され、サイドブロックの分離が簡略化されます.
    さらに、汎用モジュールを観測可能モジュールに分離し、観測可能な値を使用する部分を「オブザーバ」(Subscriber)に分離することで、SubscriberがConsumerの役割としてのみ使用されることに集中できます.
    ここでのメンテナンス方法は、パイプ方法の内部にあり、スキャン上のthrottle関数部分からCustom Operatorと定義されている.今はソースの量が少ないので、置いておきましょう.
    Observerableは、不活性な実行を実行します.これはsubscribe()が完了するまで、Observerableが演算を実行し、値をSubscriberに渡すためです.EventEmitterは、自分が最初に出した行為とは異なる操作を実行します.
    RxJSを通じて、開発者の悲願事業である注目点の分離、最適化にさらに近づくことができ、非常に有意義な一日でした.読んでくれてありがとう!