ChannelMessagingAPIを見てください
Service Workers は、メインのJavaScriptスレッドから分離されています。 特別な種類のWebワーカーであるため、同じ制限があります。 どのようにしてメインスレッドに戻って通信しますか? ブラウザは、チャネルメッセージングAPIを提供します。 このAPIを使用すると、2つのスクリプトが、共有チャネルで単純なメッセージを渡すことによって通信できます。
iframeとの通信も便利ですが、この投稿ではワーカーのユースケースに焦点を当てます。
チャネルをインスタンス化する
次の構文を使用して、チャネルをインスタンス化できます。
const channel = new MessageChannel()
タイプMessageChannel
のchannel
オブジェクトでは、port1
とport2
の2つのポートにアクセスできます。
要点は、チャネルの両端で一方のポートでリッスンし、もう一方のポートにメッセージを送信することです。
チャネルを作成するときは、メッセージをport2
に送信します。
チャネルを介したメッセージの送信
postMessage()
メソッドを使用してチャネルを介してメッセージを送信します。このメソッドは、スクリプトがブラウザーで実行されている場合、window
オブジェクトで使用できます。
const data = { color: 'green' } const channel = new MessageChannel() window.postMessage(data, [channel.port2])
受信側で着信メッセージを聞く
受信側では、たとえばService Workerで、self
にリスナーを追加します。これは、ワーカーが自分自身にアクセスする必要があるグローバルです。
self.addEventListener('message', event => { console.log('Incoming message') })
パラメータとして渡されたevent
オブジェクトには、data
プロパティでこのイベントに関連付けられたデータが含まれています。
self.addEventListener('message', event => { console.log('Incoming message') console.log(event.data) })
メッセージを送り返す
メッセージを送り返すために、イベントリスナーでは、event.ports[0]
を参照して他のポートにアクセスできます。
このオブジェクトでは、postMessage()
を呼び出して、追加のデータをポストバックできます。
self.addEventListener('message', event => { console.log('Incoming message') console.log(event.data) const data = { shape: 'rectangle' } event.ports[0].postMessage(data) })
送信者としてメッセージを受信する
送信者は、作成したチャネルオブジェクトにアクセスできるため、onmessage
ハンドラーをmessage.port1
オブジェクトにアタッチできます。
channel.port1.onmessage = event => { console.log(event.data) }
どんなメッセージを送ることができますか?
postMessage()
では、基本的なJavaScriptデータ型を送信できます。 これは、ブール値、文字列、数値、およびオブジェクトを意味します。 配列を使用して、複数のオブジェクトを渡すことができます。