Web Worker: 現在のメイン (ウィンドウ) スレッドとは別のスレッドでバックグラウンドでスクリプトを実行する方法。
- Web ワーカーと、event_loop を使用した非同期
- Web ワーカー入門
- Web ワーカーの作成方法
- Web ワーカーの例
- Web ワーカーの制限
- Web Workers の非同期操作
1. Web ワーカーとイベント ループを使用した非同期操作
JavaScript は通常、対応するキュー (マクロタスク キュー、マイクロタスク キュー) にタスクを配置することによって非同期操作を処理します。イベント ループはこれらのキューを継続的にチェックし、実行の準備ができたらタスクをコール スタックにプッシュします。このアプローチでは、ノンブロッキングの実行が保証されますが、すべてが単一のスレッドで実行されます。
一方、Web Workers では、独自のコール スタック、非同期キュー、イベント ループを備えた完全に別個のスレッドでスクリプトを実行できます。この分離により、ワーカーが独立して動作するため、メインスレッドが重い計算や長時間実行されるタスクによってブロックされるのを防ぎます。
2.
Web ワーカー入門
Web ワーカーは、メイン ウィンドウのコンテキストとは異なるコンテキストでスクリプトを実行し、Web アプリケーションでの並列処理を可能にします。
Web Worker API は、いくつかのタイプのワーカーを提供します:
- 専用ワーカー: 単一のスクリプトによって使用され、メインスレッドからタスクをオフロードするのに最適です。
- 共有ワーカー: 異なるコンテキスト (異なるウィンドウや iframe など) で実行されている複数のスクリプトからアクセスできます。
- サービス ワーカー: Web アプリケーション、ブラウザ、ネットワーク間のプロキシ サーバーとして動作し、オフライン サポートやキャッシュなどの機能を提供します。
この記事では、実装が最も簡単で一般的に使用される
専用ワーカーに焦点を当てます。
3.
Web ワーカーの作成方法
Web ワーカーを作成するには、次の主要なメソッドを使用できます:
- new Worker(): 新しいワーカーを作成するコンストラクター。
- postMessage(): メインスレッドからワーカーに、またはその逆にメッセージを送信します。
- onmessage: ワーカーが受信したメッセージを処理するために設定されたコールバック関数。
- terminate(): ワーカーを直ちに停止します。
4.
簡単な例
API からデータ、特に Dog CEO API から犬の画像を取得するワーカーを作成しましょう。
4.1 ワーカーコード
ワーカー スクリプトの実装は次のとおりです。ワーカー内では、self がグローバル コンテキストを参照するために使用されていることに注意してください:
if (window.Worker) {
const worker = new Worker("/src/worker.js");
ワーカー.postMessage({
オペレーション: "get_dog_imgs",
URL: "https://dog.ceo/api/breeds/image/random",
count: 5 //写真の数
});
worker.onmessage = (e) => {
console.log(e.data);
if (e && e.data) {
setdata((old) => [...old, e.data]); // 反応状態を更新します
showCallStack(); // コールスタックを表示する関数
}
};
worker.onerror = (e) => {
コンソール.ログ(e);
};
}
if (window.Worker) {
const worker = new Worker("/src/worker.js");
worker.postMessage({
operation: "get_dog_imgs",
url: "https://dog.ceo/api/breeds/image/random",
count: 5 //number of photos
});
worker.onmessage = (e) => {
console.log(e.data);
if (e && e.data) {
setdata((old) => [...old, e.data]); // update react state
showCallStack(); // function to show the callstack
}
};
worker.onerror = (e) => {
console.log(e);
};
}
このコードでは、ワーカーはメッセージ (onmessage) をリッスンし、指定された URL からカウントで指定された回数だけデータを取得します。
ワーカー内の呼び出しスタックは次のようになります:
4.2 クライアントコード
メインスレッドは次のようにワーカーを使用します:
self.onmessage = (イベント) => {
const データ = イベント.データ;
if (データ && data.url && data.count) {
fetchFromUrls(data.url, data.count);
}
}
// 単一のデータを取得します
const fetchdata = async (url) => {
const res = await self.fetch(url);
return await res.json();
};
const fetchFromUrls = async (url, count) => {
showCallStack(); // ワーカーのコールスタックを表示します
for (const i of new Array(count).fill(0)) {
let data = await fetchdata(url);
if (データ && データ.メッセージ) {
self.postMessage({ タイプ: "img", データ: data.message });
}
}
};
if (window.Worker) {
const worker = new Worker("/src/worker.js");
worker.postMessage({
operation: "get_dog_imgs",
url: "https://dog.ceo/api/breeds/image/random",
count: 5 //number of photos
});
worker.onmessage = (e) => {
console.log(e.data);
if (e && e.data) {
setdata((old) => [...old, e.data]); // update react state
showCallStack(); // function to show the callstack
}
};
worker.onerror = (e) => {
console.log(e);
};
}
このコードは、ワーカーにメッセージを送信し、メイン スレッドでフェッチされたデータを受信する方法を示します。
完全なコードについては code にアクセスしてください
5.
Web ワーカーの制限
Web ワーカーはメイン ウィンドウ スレッドとは別のスレッドで実行されますが、次のような制限があります。
- DOM へのアクセスなし: ワーカーは DOM を直接操作できません。 UIを更新するにはメインスレッドとの通信が必要です。
- リソース消費: Web ワーカーを使いすぎると、各ワーカーが独立して動作するために追加のリソースが必要になるため、メモリ使用量が高くなる可能性があります。