最初から、パブサブ


私に従って、トピックや改善についてのご提案を取るに満足

NGRX is an implementation of the Redux pattern. The Redux pattern is itself a publish/subscribe pattern also called Pub-Sub. Essentially this pattern is about one key thing, when a change happens it might be the concern of one or many parts of your application and you need a way to convey that change. You also need a way to do so without your code being coupled


OK、それから始めからこれをとって、パブSub、Redux、我々が必要とするタイプスクリプトと若干の基本的なRxjs、これ以上混乱していないことを学んでください.
この記事はシリーズの一部です.
  • 最初から、パート1、パブサブ、我々はここにいます

  • コアコンセプトと異なる実装

  • NGRXストア、これは、ストアの基本的な使用方法をカバーしています
  • 最初から、パートIV、NGRX効果、進行中
  • ngrx -最初から、一部のv、ngrxエンティティ、進行中
  • 本稿では以下を取り上げます.

  • パブサブ、それは何であり、なぜ我々はそれを必要とする

  • メッセージと通信、パブのサブパターンの実装とどのように我々はそれを適用することができます任意のコンポーネントベースのライブラリ/フレームワークを使用しています.
  • パブサブの必要性


    我々が最初に言ったように、NGRXはReduxの実装です、そして、我々が本当に我々のアプリケーションに加えるものは、システムの変化があるとき、メッセージを放送するためにパブSubをする能力です.OK、いつそれが起こるの?さて、あなたは特定の言語にあなたのアプリを設定して、あなたはその言語を変更する必要があります想像してください何が起こるか?まあ、おそらく可能性のある特定の言語は、あなたのアプリケーションは、その選択した言語に部品またはすべてのアプリケーションを翻訳していることを意味します.だから言語がいくつかの翻訳が発生する必要が導入されている場合、質問はあなたのアプリの一部が影響を受けているか?あなたはおそらく私よりもこれを知っているが、いくつかの推論を導入しようとしましょう.あなたのアプリケーションは、おそらくメンテナンスを容易にするいくつかのコンポーネントに分割されます.あなたのアプリが1ページあたり1つのコンポーネントがあなたがPub - Noを必要としないページの数から成るならば.

    Huh?


    あなたは5ページと1ページあたりの1つのコンポーネントを言うと言う簡単なアプリを持っている場合は、あなたが立っているページに影響を与える必要がある新しい言語に変更するとき.その時点で、おそらくこれらの新しい翻訳を擬似的なコードで求めているサービスを呼び出します.
    function onLanguageChange(newLang) {
      service.getTranslationsByLang(newLang);
    }
    
    今、あなたはこの新しい翻訳を取る方法を理解する必要がありますので、以下のようにあなたのサイトにそれらを適用する
    function onLanguageChange(newLang) {
      const translations = service.getTranslationsByLang(newLang);
      this.title = translations.title;
      this.description = translations.description
    }
    
    それから、あなたがこのページから別のページに変わるとき、あなたは上記のような何かをする必要があります、しかし、コンストラクタで、または、可能な限り早くngOnInit , 以下のように:
    constructor(){
      const translations = service.getTranslationsByLang(newLang);
      this.title = translations.title;
      this.description = translations.description
    }
    

    So when do I need Pub/Sub?


    ページ上の多くのコンポーネントを持っているとすぐに、言語の変更のようなアプリケーション全体の変更を行うと、たとえば、変更が起こったすべてのコンポーネントを伝える必要があることを気にする必要があります.今、あなたが角度を使用している場合は、それらを使用して、それらのコンポーネントにプロパティを設定することができます@Input バインディングが、すぐに非常にもつれた混乱になる、私はあなたを示すことができます
    class Component {
      private _lang = '';
    
      @Input('language')
      set lang(value) {
        this._lang = value; 
        const translations = service.getTranslationsByLang(newLang)
        this.title = translations.title;
        this.description = translations.description;
      };
      get language() {  
        return this._lang;
      }
    }
    
    感じがビット結合右と多くの書き込みに?

    メッセージ通信


    この時点で、おそらく、おそらく10の異なるコンポーネントの上記のコードを書いているとして、傷は本物です.あなたは、呼び出しを省略する良い方法を考え出すかもしれませんservice.getTranslationsByLang そして、1つの中央の場所でそうするだけで、我々は翻訳を送るだけです.
    どのような痛みから構成される?ああ、今、私たちは正しい質問をしています、傷つくことは3 - 4行を書く必要があるからではありません、そして、正しい翻訳をコンポーネントの各々の資産に割り当てる必要があります-傷つくことは我々がコンポーネントのX数に言語をセットするために特性を使用するのでです.この情報を通信するその方法は非常に結合され、また、我々が使用している特定のフレームワークに非常に依存しています.

    Ok, so what's a better way to do it?


    より良い方法はメッセージと通信することです.メッセージとの通信は、送信者と1つ以上のリスナーを持っていることを意味します.これを行うには多くの方法があります.以下はリストです.
  • バニラ実装の使用
  • ライブラリeventエミッタの使用
  • Rxjsの使用
  • この記事を長すぎてはいけませんが、最初のケースを実装しましょう.

    バニラ実装


    実装では、ライブラリを使用しないで、次の手順を実行する必要があります.
  • メッセージを送る方法が必要だ
  • 購読する方法、メッセージを取り消す方法
  • では、簡単な実装を見てみましょう.
    class PubSub {
      constructor() {
        this.listeners = [];
      }
    
      send(messageType, message) {
        this.listeners.forEach(l => l(messageType, message));
      }
    
      subscribe(listener) {
        this.listeners.push(listener);
      }
    
      unsubscribe(list) {
        this.listeners = this.listeners.filter( l => l !== list);
      } 
    
    }
    
    module.exports = PubSub;
    
    上記の実装では、send() 方法及び方法subscribe() and unsubscribe() リスナーを追加/削除するには、WAIOを与えます.これはPUB - SUBを行うために必要なことです.
    スピンのためにこれを取ってください.
    const PubSub = require('./pubsub');
    
    const ps = new PubSub();
    
    const l1 = (type, message) => {
      console.log('sub1');
      console.log(`Type: ${type}, Message: ${message} `);
    };
    
    const l2 = (type, message) => {
      console.log('sub2');
      console.log(`Type: ${type}, Message: ${message} `);
    }
    
    ps.subscribe(l1)
    
    ps.subscribe(l2)
    
    ps.send('INCREMENT', 1);
    ps.send('language', 'en');
    
    ps.unsubscribe(l1);
    
    ps.send('spam', 'hello');
    
    我々は2つのリスナーを定義する上で見ることができますl1 and l2 . 両方のリスナーは、我々の購読PubSub クラス.それから私たちはl1 呼び出しによるリスニング停止unsubscribe() . プログラムを実行すると、次の出力が得られます.

    出力は、両方のリスナーがメッセージを取得する方法を示しますINCREMENT and language 一方のみl2 メッセージを取得するspam ASl1 そのメッセージの前にアンサブスクライブできました.
    を、我々PubSub クラスは動きそうです.それで、これで何がポイントですか?アイデアは2つのことを示すことです.
  • メッセージ通信
  • ゆるく結合されている方法で通信する、すなわち、我々は、角度、Vue、反応または我々が使用するどんなライブラリの実装詳細に頼っていません.
  • 言語を変更するコンポーネントに適用するには、次のコードを取得します.
    // PubSub.js
    
    class PubSub {
      constructor() {
        this.listeners = [];
      }
    
      send(messageType, message) {
        this.listeners.forEach(l => l(messageType, message));
      }
    
      subscribe(listener) {
        this.listeners.push(listener);
      }
    
      unsubscribe(list) {
        this.listeners = this.listeners.filter( l => l !== list);
      } 
    
    }
    
    const pubSub = new PubSub();
    
    module.exports = pubsub;
    
    上記の変更PubSub クラスのインスタンスを作成するPubSub そして、それは我々がエクスポートしているそのインスタンスです.
    // sending component
    import PubSub = require('./pubsub');
    
    class Component {
      constructor() {
      }
    
      setLanguage() {
        pubsub.send('changeLanguage', 'en');
      }
    
    }
    
    上記の送信コンポーネントはPubSub インスタンスを呼び出し、メソッドを呼び出してメッセージを送信するsend() .
    // listening component
    import PubSub = require('./pubsub');
    
    class OtherComponent {
      constructor() {
        pubsub.subscribe(this.onMessage.bind(this));   
      }
    
      onMessage(type, message) {
        if (type === 'changeLanguage') {
          const translations = service.getTranslationsByLang(message);
          this.title = translations.title;
        }
      }
    }
    
    リスニングコンポーネントは、PubSub を設定し、onMessage() コンストラクタのリスナーとしてのメソッド.同じonMessage() メッセージが送信されるとメソッドが呼び出されます.注意すべきことは、送信されるメッセージがタイプ1であることをチェックする方法ですchangeLanguage 我々が行く前に、翻訳サービスから新しい翻訳を取得します.

    概要


    記事はNGRXとREDUXの両方に対する基礎となるパターンについて話をするためにセットされます、すなわち、1つまたは多くのリスナーにメッセージを送る能力.我々はそれを必要とするときに議論し、非常に簡単な実装を構築したPubSub そして、どのように我々のコンポーネントでそれを使用できるかを示した.
    次の部分では、我々はパブサブのより専門的なバージョンであるパターンReduxを特に見ます.そして、本質的に同じパターンです、しかし、我々の現在の状態の記憶と状態を変えるより安全な方法で.