機能をWeb労働者に伝える方法


Webワーカーズは、JavaやC +などの言語で共通のマルチスレッド操作に似たものを許します.フロントエンドの世界では、彼らはまだ頻繁に使用されるツールです.
それは私の意見では、主に彼らのユースケースについての知識不足、ほとんどの人が高速のPCと現代のブラウザを持っているという誤った判断、そして私が知っているものに固執する習慣の力を持っています.さらに、それらの関数へのいくつかの制限があります.

Webワーカーを利用する理由
Webワーカーは、バックグラウンドで実行される単なるスクリプトであり、他のスレッドでは、どんな高価な計算でもUIのスレッドをブロックしないことを意味します.それは巨大です.人々がウェブサイトが遅くなったり、さらに悪いことになると、人々は嫌いです.Webワーカーを使用すると、ユーザーはローディングインジケータを表示しながら、バックグラウンドで重いリフティングを行うことができますし、彼または彼女はその間に何を行うことができます.
これが役に立つとき、あなたは尋ねるかもしれません.我々は再帰的なツリー構造で働いたとき、これを良い使用に入れました.私たちは、ツリーがツリーとやり取りされるたびに、ツリー全体を何千ものノードで処理していました.それは計算の負荷を含んでいました、そして、我々が主な糸のそれのすべてをしたならば+終わりで結果を提出してください、最もものすごいPCセットさえそれについて唸ったでしょう.

Web労働者の制限
Webワーカーが別のスレッドで動作するため、できるだけ制限があります.
  • それは直接DOMにアクセスすることができません、そして、あなたは窓オブジェクトへの直接アクセスを失います.
  • あなたはそれらの中のグローバルな状態に頼ることができません.
  • あなたはstructured cloneアルゴリズム
  • で扱うことができないデータを送ることができません
    最後は、私にとって最も痛いことであることがわかりました.Webワーカーのインスタンスがある場合は、postMessageを通してデータを送信することができます.
    worker.postMessage({
        string: 'string',
        number: 0,
        array: [],
        ...
    });
    
    上の値型は、構造化されたクローニングで処理できます.しかし、関数を呼び出すことはできません.これは問題であった.なぜなら、それぞれのノードのための評価器(例えば、その名前が検索語にマッチするかどうか)を送信したかったからである.
    transferred
    機能制限の克服
    この方法を解決するための簡単なトリックです.特に、ここでの機能がファーストクラスの市民であるので、特にJavaScriptでは、我々はオブジェクトの中で機能を定義して、JSON.stringifyを通してそれらをstringifyするかもしれません.これは関数宣言を少し変換しますので、それらを解析するには少しの努力が必要です.幸いにも、それはよく両方の方法を扱う プラグインがあります.
    そしてそれが必要です.これで、jsonfnで文字列化されたWebワーカーの関数を含む宣言とオブジェクトを指定できます.
    // From main thread
    worker.postMessage({
        myFunction: JSONfn.stringify( (arg) => ... )
        payload: ... // any kind of data, let the function decide whether it's useful
    });
    
    Webワーカースクリプトの内部で再構築
    // inside of worker
    self.addEventListener("message", function(e) {
        // `e.data` contains data sent from main thread
        const myFunction = JSONfn.parse(e.data.myFunction);
        myFunction(e.data.payload); // reconstructed and callable
    });
    
    ご覧の通り、異なる引数を必要とするいくつかの関数があれば、注意しなければなりません.これは、例えば、いくつかの観測者がディスパッチャを購読し、データを受信すると、ペイロードを処理し、そのメッセージを使用できるかどうかを判断しなければならない.それは同じです.私が見つけた最もスケーラブルなオプションは2つの安定したパラメタ、関数のための1とそれらの引数のための1つを単に配列の両方でそれを送ることです.次に、イベントが発生したときは、すべての引数をすべての関数に送り、それらを処理させます.
    JSONfn
    クラスについてのサイドノート
    クラスを使用する場合、上記のアプローチは動作しないことに注意してください.保守性と読みやすさの観点から、それはクラスとタイプスクリプトインターフェイスを使用するのに完全な意味をしたでしょうが、それは可能ではありません.Stringifyメソッドは、直接アクセス可能な値だけを文字列にすることができます.しかし、クラスメソッドとして何かを定義するとき、それは単にオブジェクトのプロトタイプに付けられます.オブジェクト自体に直接存在しません.
    この記事はもともと に掲載されている.