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データ型を送信できます。 これは、ブール値、文字列、数値、およびオブジェクトを意味します。 配列を使用して、複数のオブジェクトを渡すことができます。