複数ページ通信を実現する JavaScript の sharedWorker の詳細な例

複数ページ通信を実現する JavaScript の sharedWorker の詳細な例

こんなことがありました。今日はGitHubで遊んでいました。最初はログインせずにいくつかのページを閲覧していましたが、あるページでログインしました。他のページに切り替えると、次のプロンプトが表示されます。

それで、これはどのように行われるのでしょうか? 1 つの方法として考えられるのは、localStorage です。特定のページにログインするときに、localStorage のステータスを変更します。他のページを表示するときに、最新のステータスを読み取ってプロンプトを表示します。

// ログインページ localStorage.setItem('login', true);

// その他のページ document.addEventListener("visibilitychange", function() {
	localStorage.setItem('ログイン') === 'true'の場合{
		alert('ログインしています。ページを更新してください');
	}
}

しかし、GitHub ではこれが行われておらず、localStorage に関連するフィールドは見つかりませんでした。検索してみると、sharedWorker を使用して実装されていることがわかりました。それではシェアードワーカーを見てみましょう

sharedWorkerとは

名前が示すように、sharedWorker は同じオリジンのすべてのページで共有できるワーカーの一種です。 Worker API と同様に、js URL を渡すことで sharedWorker インスタンスを登録できます。

myWorker を新しい SharedWorker('worker.js') にします。

しかし、普通の労働者とは異なります。
1 同じ js URL では、sharedWorker が 1 つだけ作成されます。他のページが同じ URL を使用して sharedWorker を作成すると、作成されたワーカーが再利用され、このワーカーはそれらのページで共有されます。
2 sharedWorkerはポートを介してメッセージを送受信します

次に、ワーカーとページ間でメッセージがどのように送受信されるかを見てみましょう。

メッセージポート

2 つの js があり、1 つはページで実行されている page.js で、もう 1 つはワーカーで実行されている worker.js であるとします。次に、page.js に sharedWorker を登録する必要があります。コードは次のようになります。

// ページ.js
myWorker を新しい SharedWorker('worker.js') にします。
// ページはワーカー ポートを通じてメッセージを送信します。myWorker.port.postMessage('hum');
// ページはワーカー ポートを介してメッセージを受信します。myWorker.port.onmessage = (e) => console.log(e.data);

// ワーカー.js
onconnect = 関数(e) {
	ポートを定数で指定します。
	port.postMessage('こんにちは');
	ポート.onmessage = (e) => {
		コンソールログ(e.data);
	}
}

sharedWorker のデバッグ

上記の例では、ワーカーで console.log を使用してページからメッセージを出力しましたが、出力されたログはどこで確認できるでしょうか?ブラウザのアドレスバーに「chrome://inspect」と入力すると、
をクリックし、サイドバーで共有ワーカーを選択すると、ブラウザで現在実行中のすべてのワーカーが表示されます。 「検査」をクリックすると開発者ツールが開き、出力ログが表示されます。

ここで、ワーカー名が untitled であることがわかります。これは、sharedworker コンストラクターが 2 番目のパラメーターを名前として渡すこともサポートしているためです。

myWorker を新しい SharedWorker('worker.js', '素晴らしいワーカー') にします。

複数のページにメッセージを投稿する

記事の冒頭の例に戻りましょう。ページとワーカー間の通信を実装しました。では、ワーカーが複数のページにメッセージを送信できるようにするにはどうすればよいでしょうか。 1 つのアイデアは、ポートをポート プールとしてキャッシュすることです。これにより、すべてのページにメッセージをブロードキャストする必要がある場合に、ポートをトラバースしてメッセージを送信できます。

// ワーカー js
ポートプール
onconnect = 関数(e) {
	ポートを定数で指定します。
	// 接続時に portPool にポートを追加します portPool.push(port);
	port.postMessage('こんにちは');
	ポート.onmessage = (e) => {
		コンソールログ(e.data);
	}
}

関数ボードキャスト(メッセージ) {
	portPool.forEach(ポート => {
		port.portMessage(ポート);
	})
}

このようにして、基本的に複数のページにメッセージをブロードキャストする機能を実現しました。

無効なポートをクリアする

上記の実装には問題があります。ページが閉じられた後、workerPool 内のポートが自動的にクリアされず、メモリが無駄になります。ページが閉じられる前に、ページが閉じられることを共有ワーカーに通知し、ワーカーに無効な messagePort を portPool から削除させることができます。

// ページ window.onbeforeunload = () => {
  myWorker.port.postMessage('閉鎖予定');
};

// ワーカー.js
ポートプール
onconnect = 関数(e) {
  var ポート = e.ports[0];
  ポートプールをプッシュします。
  port.onmessage = 関数(e) {
    コンソールログ(e);
    if (e.data === '閉鎖予定') {
      const インデックス = ports.findIndex(p => p === port);
      ポートプール.splice(インデックス、1);
    }
    var workerResult = '結果: ' + (e.data[0] * e.data[1]);
    ポート。
  }
}

関数ボードキャスト(メッセージ) {
	portPool.forEach(ポート => {
		port.portMessage(ポート);
	})
}

このようにして、複数ページのブロードキャスト用のシンプルな sharedWorker を実装しました。これを使って時間をブロードキャストすることができます:

setInterval(() => boardcast(Date.now()), 1000);

参照する

https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker
https://github.com/mdn/simple-shared-worker

JavaScript で sharedWorker を使用してマルチページ通信を実現する方法については、これで終わりです。js sharedWorker マルチページ通信に関するその他の関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • プロセス解析を使用する Javascript Web Worker
  • Yii2 と Workerman の Websocket の例を組み合わせた詳細な説明
  • JavaScript での Web ワーカー マルチスレッド API の研究
  • Node.js のワーカー スレッドの詳細な理解
  • nodejs で worker_threads を使用して新しいスレッドを作成する方法
  • Javascript ワーカー サブスレッド コード例
  • JavaScript でのワーカー イベント API の理解
  • JS で webWorker を使用する方法

<<:  Linux仮想マシンをWiFiに接続する方法

>>:  CentOS インストール mysql5.7 詳細チュートリアル

推薦する

小規模プログラムへのデータキャッシュ機構の応用と実装

ミニプログラムデータキャッシュ関連知識データ キャッシュ: データをキャッシュして、アプレットを終了...

Linuxのdateコマンドの使用

1. コマンドの紹介date コマンドは、現在の時刻または指定された時刻を指定された形式で表示するた...

Vueのコンポーネントのprops属性について詳しく説明します

目次質問1: 小道具は具体的にどのように使用されますか?原理は何ですか?下を見る質問 2: 年齢に ...

Dockerでイメージ情報を表示する方法

この記事では、Dockerでイメージ情報を表示する方法を学ぶ必要があります。 1. imagesコマ...

Linux のハードリンクとソフトリンクの原理と使用法の分析

Linux システムには、ファイル共有を解決するために使用できるリンク ファイルと呼ばれる種類のファ...

Docker+K8S+GitLab/SVN+Jenkins+Harbor をベースにした継続的インテグレーション配信環境の構築に関する詳細なチュートリアル

目次環境設定の概要1.K8Sとは何ですか? 2. K8S を使用する理由3. K8S を使用する利点...

JavaScriptはスクロールバーの位置を取得し、ページをアンカーポイントまでスライドします。

序文この記事は、私が最近仕事で遭遇した問題を記録したものです。アプリネイティブとフロントエンドのh5...

ふるい抽選を実施するミニプログラム

この記事の例では、ふるい抽選を実装するためのミニプログラムの具体的なコードを参考までに共有しています...

tbodyタグの魔法はテーブルコンテンツの表示を高速化します

他の人のウェブページを保存して見たことがあると思いますが、特にdwで開くと、多くのウェブページに&l...

垂直方向の中央揃えをエレガントに実現する方法を教えます(推奨)

序文CSS で水平方向と垂直方向に中央揃えする方法はたくさんあります。この記事で紹介する方法は非常に...

上下に空白行があるフォームを挿入する解決策

ウェブページを作成するときに、フォームを挿入した後、フォームの上下に空白行が表示されることがよくあり...

MYSQLは、ショッピングカートに追加する際に重複追加を防ぐためのサンプルコードを実装します。

序文最近、仕事の都合で、APP ショッピングカートの注文支払いに取り組んでいました。テスト中にバグが...

Vueがsweetalert2プロンプトコンポーネントを統合する際の問題についてお話ししましょう

目次1. プロジェクト統合1. CDNインポート方法: 2. 箱の梱包を確認する3. 迅速な箱詰め4...

MySQLのunion allとunionの違いを簡単に理解する

Union は、重複行を除外し、デフォルトのソートを実行する、データに対する結合操作です。Union...

Ubuntuサーバーの一般的なコマンドの概要

以下のコマンドのほとんどは、コンソール/ターミナル/シェルで入力する必要があります。 'su...