WorkerComはWebワーカーを楽しいものにします。 Workercomは小さなライブラリ(1.1kb)であり、 postMessageについて考えることの精神的障壁を取り除き、労働者と一緒に働いているという事実を隠します。 Comlinkからのコミュニケーションの問題を書き直し、改善しました
より抽象的なレベルでは、それはpostMessageとES6プロキシのRPC実装です。
$ yarn add workercom
Comlink.proxy関数を削除します(workercomは関数を見つけ、転送して水分補給します)function 、 class 、 Errorファミリ、 TypedArrayファミリなどのデフォルトの変換サポートES6プロキシサポートのないブラウザは、プロキシポリフィルを使用できます。
サイズ:〜2.5k、〜1.2k gzip'd、〜1.1k brotli'd
携帯電話、特にローエンドの携帯電話では、メインスレッドを可能な限りアイドル状態に保ち、ユーザーのインタラクションに迅速に応答し、Jankフリーエクスペリエンスを提供できるようにすることが重要です。 UIスレッドは、UI作業のみである必要があります。ウェブワーカーは、別のスレッドでコードを実行できるWeb APIです。別のスレッドと通信するために、ウェブワーカーはpostMessage APIを提供します。 JavaScriptオブジェクトをmyWorker.postMessage(someObject)を使用してメッセージとして送信し、ワーカー内のmessageイベントをトリガーできます。
WorkerComは、このメッセージをかけたベースのAPIを、RPC実装を提供することにより、開発者に優しいものに変えます。1つのスレッドからの値は、ローカル値と同じように他のスレッド内(および逆)内で使用できます。
main.js
import { wrap } from "workercom" ;
import Worker from "worker-loader!./worker.js" ;
async function init ( ) {
const worker = new Worker ( ) ;
// WebWorkers use `postMessage` and therefore work with Workercom.
const obj = wrap ( worker ) ;
alert ( `Counter: ${ await obj . counter } ` ) ;
await obj . inc ( ) ;
alert ( `Counter: ${ await obj . counter } ` ) ;
}
init ( ) ;worker.js
import { expose } from "workercom" ;
const obj = {
counter : 0 ,
inc ( ) {
this . counter ++ ;
} ,
} ;
expose ( obj ) ;main.js
import { wrap } from "workercom" ;
import Worker from "worker-loader!./worker.js" ;
async function init ( ) {
const remoteFunction = wrap ( new Worker ( ) ) ;
await remoteFunction ( callback ( value ) {
alert ( `Result: ${ value } ` ) ;
} ) ;
}
init ( ) ;worker.js
import { expose } from "workercom" ;
async function remoteFunction ( cb ) {
await cb ( "A string from a worker" ) ;
}
expose ( remoteFunction ) ;SharedWorker SharedWorkerでworkercomを使用する場合、次のことが必要です。
Workercom.wrapを呼び出すときに、 SharedWorkerインスタンスのportプロパティを使用します。onconnectコールバック内のWorkercom.expose呼び出します。プロのヒント: chrome:// inspect/#workersに行くことにより、現在Chromeで走っている共有労働者のDevToolsにアクセスできます
main.js
import { wrap } from "workercom" ;
import SharedWorker from "worker-loader?worker=SharedWorker!./worker.js" ;
async function init ( ) {
const worker = new SharedWorker ( ) ;
/**
* SharedWorkers communicate via the `postMessage` function in their `port` property.
* Therefore you must use the SharedWorker's `port` property when calling `Workercom.wrap`.
*/
const obj = wrap ( worker . port ) ;
alert ( `Counter: ${ await obj . counter } ` ) ;
await obj . inc ( ) ;
alert ( `Counter: ${ await obj . counter } ` ) ;
}
init ( ) ;worker.js
import { expose } from "workercom" ;
const obj = {
counter : 0 ,
inc ( ) {
this . counter ++ ;
} ,
} ;
/**
* When a connection is made into this shared worker, expose `obj`
* via the connection `port`.
*/
onconnect = function ( event ) {
const port = event . ports [ 0 ] ;
expose ( obj , port ) ;
} ;
// Single line alternative:
// onconnect = (e) => expose(obj, e.ports[0]); Workercom.wrap(endpoint)およびWorkercom.expose(value, endpoint?) WorkerComの目標は、一方のスレッドからの露出値を他のスレッドで利用できるようにすることです。 expose 、 endpointがpostMessageのようなインターフェイスであるendpointでvalueを公開します。
wrapメッセージチャネルのもう一方の端をラップし、プロキシを返します。プロキシには、露出した値のすべてのプロパティと関数がありますが、アクセスと呼び出しは本質的に非同期です。これは、数値を返す関数が数字の約束を返すことを意味します。経験則として:プロキシを使用している場合は、その前にawaitください。例外はキャッチされ、反対側で再発されます。
Workercom.installTransfer(name, transferables) & Comlink.proxyデフォルトでは、構造化されたクローニングの意味で、すべての関数パラメーター、返品値、およびオブジェクトプロパティ値がコピーされます。構造化されたクローニングは、深いコピーと考えることができますが、いくつかの制限があります。詳細については、このテーブルを参照してください。
値をコピーするのではなく転送したい場合 - 値が転送可能である場合、またはTransferableが含まれている場合はinstallTransfer()呼び出しに値をラップし、転送可能な値のリストを提供できます。
import { installTransfer } from "workercom" ;
installTransfer < ArrayBuffer , string > ( "arraybuffer" , {
canHandle : ( value ) => value instanceof ArrayBuffer ,
serialize : ( value ) => [ _arrayBufferToBase64 ( value ) , [ ] ] ,
deserialize : ( { raw } ) => _base64ToArrayBuffer ( raw ) ,
} ) ; Comlink.proxy()を削除しました。これは自動的に発生します
// myProxy.onready = Comlink.proxy((data) => {
// /* ... */
// });
// * And now
myProxy . onready = ( data ) => {
/* ... */
}その他のデフォルトの転送を参照してください
イベントリスナーを追加して、イベントソースが別のスレッドにあるイベントリスナーを追加することがよくあります。
button . addEventListener ( "click" , myProxy . onClick . bind ( myProxy ) ) ;これはすぐには投げませんが、 onClick実際には呼ばれません。これは、 Eventが構造化されたクローン可能でも転送可能でもないためです。回避策として、WorkerComは転送ハンドラーを提供しています。
各関数パラメーターと戻り値は、すべての登録転送ハンドラーに与えられます。イベントハンドラーの1つがcanHandle()からtrueを返すことで値を処理できることを信号した場合、構造化されたクローン可能なデータに値をシリアル化し、値を脱上する責任があります。メッセージチャネルの両側に転送ハンドラーがセットアップされています。これがイベントのための例の転送ハンドラーです:
installTransfer < Event , {
target : {
id : string ;
classList : string [ ]
}
} > ( "EVENT" , {
canHandle : ( obj ) => obj instanceof Event ,
serialize : ( ev ) => {
return [
{
target : {
id : ev . target . id ,
classList : [ ... ev . target . classList ] ,
} ,
} ,
[ ] ,
] ;
} ,
deserialize : ( obj ) => obj ,
} ) ;この特定の転送ハンドラーは実際のEventを作成するのではなく、 event.target.idおよびevent.target.classListプロパティを備えたオブジェクトだけです。多くの場合、これで十分です。そうでない場合は、転送ハンドラーを簡単に拡張して、必要なすべてのデータを提供できます。
function 、 class 、 Errorファミリ、 TypedArrayファミリのデフォルトの変換サポート
Workercom.releaseProxy WorkerComによって作成されたすべてのプロキシには[releaseProxy]メソッドがあります。それを呼び出すと、プロキシと露出したオブジェクトがメッセージチャネルから切り離され、両端が収集されることを可能にします。
const proxy = wrap ( port ) ;
// ... use the proxy ...
proxy [ releaseProxy ] ( ) ;Workercom.createEndpoint WorkerComによって作成されたすべてのプロキシには[createEndpoint]メソッドがあります。それを呼び出すと、 [createEndpoint]が呼び出されたプロキシと同じオブジェクトに接続されている新しいMessagePortが返されます。
const port = myProxy [ createEndpoint ] ( ) ;
const newProxy = wrap ( port ) ;Workercom.windowEndpoint(window, context = self, targetOrigin = "*") WindowsとWebワーカーには、 postMessageのわずかに異なるバリエーションがあります。 workercomを使用してiframeまたは別のウィンドウと通信する場合は、 windowEndpoint()でラップする必要があります。
windowは、通信する必要があるウィンドウです。 context 、 windowからのメッセージを受信できるEventTargetです(多くの場合self )。 targetOriginは、 postMessage後に通過し、原点ごとにメッセージをフィルタリングできます。詳細については、 Window.postMessageのドキュメントを参照してください。
使用例については、 docsフォルダーの非労働者の例をご覧ください。
WorkerComはタイプスクリプトタイプを提供します。タイプTの何かをexpose()と、対応するwrap()コールは、 Workercom.Remote<T>のタイプの何かを返します。このタイプは現在、しばらくの間バトルテストされていますが、最良の効果に基づいて実装されています。 TypeScriptのタイプシステムで正しくエンコードすることが不可能ではないにしても、信じられないほど難しいニュアンスがあります。 as unknown as <type>特定のタイプを強制する必要がある場合があります。
WorkerComは、nodeのworker_threadsモジュールで動作します。
ライセンスMIT