diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/web/api/web_workers_api | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/ja/web/api/web_workers_api')
4 files changed, 1335 insertions, 0 deletions
diff --git a/files/ja/web/api/web_workers_api/functions_and_classes_available_to_workers/index.html b/files/ja/web/api/web_workers_api/functions_and_classes_available_to_workers/index.html new file mode 100644 index 0000000000..73e94ffb7a --- /dev/null +++ b/files/ja/web/api/web_workers_api/functions_and_classes_available_to_workers/index.html @@ -0,0 +1,380 @@ +--- +title: Web Workers が使用できる関数とクラス +slug: Web/API/Web_Workers_API/Functions_and_classes_available_to_workers +tags: + - Reference + - Web + - Web Worker + - Worker +translation_of: Web/API/Web_Workers_API/Functions_and_classes_available_to_workers +--- +<p>標準的な <a href="/ja/docs/Web/JavaScript">JavaScript</a> の関数({{jsxref("String")}} や {{jsxref("Array")}}、{{jsxref("Object")}}、 {{jsxref("JSON")}} など)に加えて、DOMから worker に利用できる様々な関数があります。この記事ではそれらの機能のリストを提供します。</p> + +<p><strong>Worker は、現在の window とは異なるグローバルコンテキスト、 {{domxref("DedicatedWorkerGlobalScope")}} で実行されます。</strong>既定では {{domxref("Window")}} のメソッドとプロパティは使用できませんが、<code>Window</code> に似ている {{domxref("DedicatedWorkerGlobalScope")}} は {{domxref("WindowTimers")}} と {{domxref("WindowBase64")}} を実装しています。</p> + +<h2 id="worker_の種類別のプロパティとメソッドの比較">worker の種類別のプロパティとメソッドの比較</h2> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">関数</td> + <td class="header">専用 workers</td> + <td class="header">共有 workers</td> + <td class="header">サービス workers</td> + <td class="header">Chrome workers {{Non-standard_inline}}</td> + <td class="header">workers の外側</td> + </tr> + <tr> + <td>{{domxref("WindowBase64.atob", "atob()")}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("Window")}} で使用可能。</td> + </tr> + <tr> + <td>{{domxref("WindowBase64.btoa", "btoa()")}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("Window")}} で使用可能。</td> + </tr> + <tr> + <td>{{domxref("WindowTimers.clearInterval", "clearInterval()")}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("Window")}} で使用可能。</td> + </tr> + <tr> + <td>{{domxref("WindowTimers.clearTimeout", "clearTimeout()")}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("Window")}} で使用可能。</td> + </tr> + <tr> + <td>{{domxref("Window.dump()", "dump()")}} {{non-standard_inline}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("Window")}} で使用可能。</td> + </tr> + <tr> + <td>{{domxref("WindowTimers.setInterval", "setInterval()")}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("Window")}} で使用可能。</td> + </tr> + <tr> + <td>{{domxref("WindowTimers.setTimeout", "setTimeout()")}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("Window")}} で使用可能。</td> + </tr> + <tr> + <td>{{domxref("WorkerGlobalScope.importScripts", "importScripts()")}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>使用不可。</td> + </tr> + <tr> + <td>{{domxref("WorkerGlobalScope.close", "close()")}} {{non-standard_inline}}</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>{{domxref("WorkerGlobalScope")}} で使用可能。</td> + <td>使用可能だが、何も実行しない。</td> + <td>不明。</td> + <td>使用不可。</td> + </tr> + <tr> + <td>{{domxref("DedicatedWorkerGlobalScope.postMessage", "postMessage()")}}</td> + <td>{{domxref("DedicatedWorkerGlobalScope")}} で使用可能。</td> + <td>使用不可。</td> + <td>使用不可。</td> + <td>不明。</td> + <td>使用不可。</td> + </tr> + </tbody> +</table> + +<h2 id="worker_で使用できる_API">worker で使用できる API</h2> + +<table class="standard-table"> + <tbody> + <tr> + <td class="header">関数</td> + <td class="header">機能</td> + <td class="header">Gecko(Firefox)のサポート状況</td> + <td class="header">IE のサポート状況</td> + <td class="header">Blink(Chrome と Opera) のサポート状況</td> + <td class="header">WebKit(Safari) のサポート状況</td> + </tr> + <tr> + <td>{{domxref("Broadcast_Channel_API","Broadcast Channel API")}}</td> + <td>同じ {{glossary("origin", "オリジン")}}(通常は同じサイトのページ)で {{glossary("browsing context", "ブラウジングコンテキスト")}}(<em>window</em> 、 <em>tab</em>、<em>frame、</em>あるいは<em>iframe</em>)間の単純な通信ができる。</td> + <td>{{ CompatGeckoDesktop(38)}}</td> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{CompatNo}}</span></td> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{CompatNo}}</span></td> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{CompatNo}}</span></td> + </tr> + <tr> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{domxref("Cache", "Cache")}}</span></td> + <td>Cache API は現在のオリジンと関連付けられたキャッシュストレージを<span style="background-color: rgba(212, 221, 228, 0.14902);">プログラムで制御する機能</span>を提供する。</td> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{CompatVersionUnknown}}</span></td> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{CompatNo}}</span></td> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{ CompatChrome(43) }}</span></td> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{CompatUnknown}}</span></td> + </tr> + <tr> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{domxref("Channel_Messaging_API", "Channel Messaging API")}}</span></td> + <td> + <p>同じ document に添付されている異なるブラウジングコンテキスト(たとえば、2つのiFrame、あるいはメインの document とiFrame、{{domxref("SharedWorker")}} を介した2つの document 、あるいは2つの worker )にて、2つの別々のスクリプトが2 つのポートを介して 直接通信できる。</p> + </td> + <td>{{ CompatGeckoDesktop(41)}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{domxref("Console", "Console API")}}</span></td> + <td>ブラウザーのデバッグコンソールへのアクセスを提供する(たとえば、Firefox の <a href="/ja/docs/Tools/Web_Console">Web コンソール</a>)。どのように動作するかの詳細はブラウザーごとに異なるが、一般的に提供されている機能セットの<em>デファクト</em>である。</td> + <td>{{ CompatGeckoDesktop(38)}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td><span style="background-color: rgba(212, 221, 228, 0.14902);">{{domxref("CustomEvent")}}</span></td> + <td><strong><code>CustomEvent</code></strong> インターフェースは、あらゆる用途でアプリケーションによって初期化されるイベントを表す。</td> + <td>{{ CompatGeckoDesktop(48)}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>{{domxref("Data_Store_API", "Data Store")}}</td> + <td>複数の Firefox OS アプリケーションで、素早く効率的かつセキュアな相互のデータの保存や共有を行うための強力で柔軟なストレージ機構。</td> + <td>v1.0.1 から、Firefox OS 内部(認定の通った)アプリケーションのみ。</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("DOMRequest")}} と {{domxref("DOMCursor")}}</td> + <td>それぞれ、これらのオブジェクトは進行中の操作と(たとえば、成功時や失敗時の操作に反応するリスナを使って)、結果リストを跨いだ進行中の操作を表す。</td> + <td>{{ CompatGeckoDesktop(41)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>{{domxref("Fetch_API", "Fetch")}}</td> + <td>Fetch 仕様はリソースを取得について、最新定義と、取得用の API (たとえば、ネットワーク経由で)を提供する。</td> + <td>多くは{{ CompatGeckoDesktop(34)}} に(設定が必要)、いくつかの機能はそれ以降で。</td> + <td>{{CompatNo}}</td> + <td>{{ CompatChrome(42) }}<br> + {{ CompatChrome(41) }} 設定が必要</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("FileReader")}}</td> + <td>この API では、 {{domxref("Blob")}} と {{domxref("File")}} オブジェクトの非同期読み取りが可能。</td> + <td>{{CompatGeckoDesktop(46)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("FileReaderSync")}}</td> + <td>この API では、{{domxref("Blob")}} と {{domxref("File")}} オブジェクトの同期読み取りが可能。worker 内でのみ実行可能な API。</td> + <td>{{CompatGeckoDesktop(8)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("FormData")}}</td> + <td><code>FormData</code> オブジェクトは、XMLHttpRequest <a href="/ja/docs/DOM/XMLHttpRequest#send()" title="XMLHttpRequest#send()"><code>send()</code></a> メソッドを使用して送信できる Form フィールドとその値を表す key/value ペアのセットを簡単に構築する方法を提供する。</td> + <td>{{CompatUnknown}} ({{CompatGeckoDesktop(39)}} で実装されているはずである)</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>{{domxref("ImageData")}}</td> + <td>{{domxref("canvas")}} 要素の領域の下にあるピクセルデータ。このデータ操作は、Web Worker に委任したほうが適しているような、複雑な処理になりうる。</td> + <td>{{CompatGeckoDesktop(25)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("IndexedDB_API", "IndexedDB")}}</td> + <td>シンプルな値と階層的なオブジェクトを保持するレコードを保存するデータベース。</td> + <td>{{CompatGeckoDesktop(37)}}, {{domxref("IDBCursorWithValue")}} は {{CompatGeckoDesktop(42)}} から。</td> + <td>10.0</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/ja/docs/Web/API/Network_Information_API">Network Information API</a></td> + <td>システムの接続についての情報を汎用的な接続タイプ(例えば 'wifi', 'cellular' など)の用語で提供する。</td> + <td>{{CompatGeckoMobile(53)}} モバイルのみ</td> + <td>{{CompatVersionUnknown}} モバイルのみ</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("Notifications_API", "Notifications")}}</td> + <td>Web ページがエンドユーザーへのシステム通知の表示を制御できるようにする。</td> + <td>{{CompatGeckoDesktop(41)}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>{{domxref("Performance")}}</td> + <td><strong><code>Performance</code></strong> インターフェースは、指定されたページのタイミング関連のパフォーマンス情報を表す。</td> + <td>{{ CompatGeckoDesktop("34.0") }}</td> + <td>{{CompatUnknown}}</td> + <td>{{ CompatChrome("33.0") }}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>{{domxref("PerformanceEntry")}}, {{domxref("PerformanceMeasure")}}, {{domxref("PerformanceMark")}}, {{domxref("PerformanceObserver")}}, {{domxref("PerformanceResourceTiming")}}</td> + <td>アプリケーションのネットワークの性能についていくつかの面から詳細なデータを獲得、分析することを可能にする。</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>{{jsxref("Promise")}}</td> + <td>非同期関数を記述できる JavaScript オブジェクト。</td> + <td>{{CompatGeckoDesktop(28)}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td><a href="https://developer.mozilla.org/ja/docs/Web/API/Server-sent_events">Server-sent events</a></td> + <td>サーバーから、接続が開いた後に、あらゆる箇所のウェブページにデータをプッシュさせる。</td> + <td>{{CompatGeckoDesktop(53)}} (今のところ専用 worker と共有 worker でのみ有効; service worker では無効)</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>{{domxref("ServiceWorkerRegistration")}}</td> + <td>標準 worker の内部から service worker を登録して、関連する機能を使用できる。</td> + <td>{{CompatGeckoDesktop(40)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("TextEncoder")}} と {{domxref("TextDecoder")}}</td> + <td>特定のエンコーディングに エンコード、またはでコードできる新しい {{domxref("TextEncoder")}} や {{domxref("TextDecoder")}} を生成して返す。</td> + <td>{{CompatGeckoDesktop(20)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{ domxref("URL") }}</td> + <td> + <p>Worker にアクセスできる {{domxref("Blob")}} とともに <a href="/ja/docs/DOM/window.URL.createObjectURL" title="/ja/docs/DOM/window.URL.createObjectURL">URL.createObjectURL</a> と <a href="/ja/docs/DOM/window.URL.revokeObjectURL" title="/ja/docs/DOM/window.URL.revokeObjectURL">URL.revokeObjectURL</a> 静的メソッドを使用できる。<br> + Worker は {{domxref("URL.URL", "URL()")}} コンストラクタを使用して新しい URL を生成し、返されたオブジェクトの通常のメソッドを呼び出せる。</p> + </td> + <td>{{CompatGeckoDesktop(21)}}。URL() コンストラクタは {{CompatGeckoDesktop(26)}} から。</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("OffscreenCanvas")}} の <a href="/ja/docs/Web/API/WebGL_API">WebGL</a></td> + <td>WebGL(Web グラフィックライブラリ)は、プラグインを使用せずにブラウザー互換性を保ちながらインタラクティブな 3D と 2D レンダリングができる JavaScript API である。</td> + <td>{{CompatGeckoDesktop(44)}}(設定で有効化する)。<code>about:config</code> で、<code>gfx.offscreencanvas.enabled</code> を true に設定する。</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("WebSocket")}}</td> + <td>新しい {{domxref("WebSocket")}} オブジェクトを生成して返す。これは標準の <code>WebSocket()</code> コンストラクタの動作を模倣する。</td> + <td>{{CompatGeckoDesktop(37)}}</td> + <td>11.0</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>{{domxref("Worker")}}</td> + <td>新しい {{ domxref("Worker") }} を生成する。worker はより多くの worker を生成できる。</td> + <td>{{CompatGeckoDesktop("1.9.1")}}</td> + <td>10.0</td> + <td>{{CompatNo}} <a class="external" href="https://code.google.com/p/chromium/issues/detail?id=31666" rel="external" title="http://code.google.com/p/chromium/issues/detail?id=31666">crbug.com/31666</a> を見てください。</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>{{domxref("WorkerGlobalScope")}}</td> + <td>グローバルスコープの worker。このオブジェクトは <a href="#workerscope">Worker 特有の関数</a>を定義する。</td> + <td>{{CompatVersionUnknown}}</td> + <td>10.0</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>{{domxref("WorkerLocation")}}</td> + <td>worker で使用可能な {{domxref("Location")}} インターフェースのサブセット。</td> + <td>{{CompatGeckoDesktop(1.9.2)}}</td> + <td>10.0</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>{{domxref("WorkerNavigator")}}</td> + <td>worker で使用可能な {{domxref("Navigator")}} インターフェースのサブセット。</td> + <td> + <p>基本実装 {{CompatVersionUnknown}}<br> + {{domxref("NavigatorID.appCodeName", "appCodeName")}}、{{domxref("NavigatorID.product", "product")}}、{{domxref("NavigatorID.taintEnabled", "taintEnabled()")}}:{{CompatGeckoDesktop(28)}}<br> + {{domxref("WorkerNavigator.onLine", "onLine")}}:{{CompatGeckoDesktop(29)}}<br> + {{domxref("NavigatorLanguage")}}: {{CompatVersionUnknown}}</p> + </td> + <td>{{domxref("NavigatorID.appName", "appName")}}、{{domxref("NavigatorID.appVersion", "appVersion")}}、{{domxref("WorkerNavigator.onLine", "onLine")}}、{{domxref("NavigatorID.platform", "platform")}}、{{domxref("NavigatorID.userAgent", "userAgent")}}: 10.0<br> + Other: {{CompatNo}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + <tr> + <td>{{domxref("XMLHttpRequest")}}</td> + <td>新しい {{domxref("XMLHttpRequest")}} オブジェクトを生成して返す。これは標準の <code>XMLHttpRequest()</code> コンストラクタの動作を模倣する。<code>XMLHttpRequest</code> の <code>responseXML</code> と <code>channel</code> 属性は常に <code>null</code> を返すことに注意。</td> + <td> + <p>基本: {{CompatGeckoDesktop("1.9.1")}}</p> + + <p>{{domxref("XMLHttpRequest.response", "response")}} と {{domxref("XMLHttpRequest.responseType", "responseType")}} は、{{CompatGeckoDesktop("10")}} から使用可能。</p> + + <p>{{domxref("XMLHttpRequest.timeout", "timeout")}} と {{domxref("XMLHttpRequest.ontimeout", "ontimeout")}} は、{{CompatGeckoDesktop("13")}} から使用可能。</p> + </td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> + +<h2 id="関連項目">関連項目</h2> + +<ul> + <li><a href="/ja/docs/Web/API/Web_Workers_API/Using_web_workers">web worker を使用する</a></li> + <li>{{domxref("Worker")}}</li> +</ul> diff --git a/files/ja/web/api/web_workers_api/index.html b/files/ja/web/api/web_workers_api/index.html new file mode 100644 index 0000000000..e4d9678f40 --- /dev/null +++ b/files/ja/web/api/web_workers_api/index.html @@ -0,0 +1,99 @@ +--- +title: Web Workers API +slug: Web/API/Web_Workers_API +tags: + - API + - DOM + - Web Workers + - Workers +translation_of: Web/API/Web_Workers_API +--- +<div>{{DefaultAPISidebar("Web Workers API")}}</div> + +<p class="summary"><strong>Web Worker</strong> とは、ウェブアプリケーションにおけるスクリプトの処理をメインとは別のスレッドに移し、バックグラウンドでの実行を可能にする仕組みのことです。時間のかかる処理を別のスレッドに移すことが出来るため、 UI を担当するメインスレッドの処理を中断・遅延させずに実行できるという利点があります。</p> + +<h2 id="Web_Workers_concepts_and_usage" name="Web_Workers_concepts_and_usage">Web Worker の概念と使い方</h2> + +<p>{{DOMxRef("Worker")}} オブジェクトは {{DOMxRef("Worker.Worker", "Worker()")}} などのコンストラクターで生成されるオブジェクトで、名前を持つ JavaScript ファイルを実行します。 Worker のスレッドで実行されるコードはこのファイルに書かれており、今いる {{DOMxRef("window")}} とは別のグローバルなコンテキストの中で Worker がコードを実行します。Dedicated Worker (専用ワーカー) の場合、そのコンテキストは {{DOMxRef("DedicatedWorkerGlobalScope")}} オブジェクトで表現されます (通常の Worker は単一のスクリプトで使用されますが、 Worker を共有する際は {{DOMxRef("SharedWorkerGlobalScope")}} を使用します)。</p> + +<p>Worker のスレッドではあらゆるコードを実行できますが、いくつか例外があります。例えば、 Worker から DOM を直接操作することは出来ません。また、 {{DOMxRef("window")}} にデフォルトで用意されているメソッドやプロパティには Worker から使用できないものもあります。しかし、 <a href="/ja/docs/Web/API/WebSockets_API">WebSockets</a> や <a href="/ja/docs/Web/API/IndexedDB_API">IndexedDB</a> のようなデータストレージに加え、 Firefox OS における <a href="/ja/docs/Web/API/Data_Store_API">Data Store API</a> など、 <code>window</code> に含まれていても使用できるものは数多くあります。詳しくは <a href="/ja/docs/Web/API/Web_Workers_API/Functions_and_classes_available_to_workers">Worker から使用できる関数とクラス</a> を参照してください。</p> + +<p>Worker とメインスレッドとの間では、メッセージのシステムを通してデータがやり取りされます。両者は <code>postMessage()</code> メソッドを使ってメッセージを送信し、受け取ったメッセージには <code>onmessage</code> イベントハンドラーで返信します (メッセージは {{Event("Message")}} イベントの <code>data</code> 属性に格納されます)。なお、送信したデータは受取先でコピーされます (共有ではありません)。</p> + +<p>メインスレッドのページと同じオリジンであれば、 Web Workers は新しい Worker をいくつでも生成できます。また、 Worker はネットワーク I/O において <a class="internal" href="/ja/docs/Web/API/XMLHttpRequest"><code>XMLHttpRequest</code></a> を使用しますが、 <code>XMLHttpRequest</code> における <code>responseXML</code> と <code>channel</code> 属性は必ず <code>null</code> を返す点で通常と異なります。</p> + +<p>Dedicated Worker の他にも、 Worker の種類には以下のようなものがあります。</p> + +<ul> + <li>Shared Worker (共有ワーカー) は、 iframe などの異なる window で実行されている複数のスクリプトから利用できる Worker です。それらのスクリプトと Worker は同じドメイン内にある必要があります。スクリプトどうしがアクティブなポートで通信しなければならないので、 Dedicated Worker よりも少し複雑です。詳しくは {{DOMxRef("SharedWorker")}} を参照してください。</li> + <li><a href="/ja/docs/Web/API/ServiceWorker_API">ServiceWorker</a> は、複数のウェブアプリケーション間やブラウザ、 (利用可能なら) ネットワークとの間でプロキシサーバーとして動くものです。他の Worker とは異なり、 Service Worker はオフラインでのユーザーエクスペリエンスを実現するために設計されています。ネットワークへのリクエストに割り込み、オンライン・オフラインそれぞれの場合に適した結果をユーザに返します。また、サーバ上のリソースの更新も担います。 Service Worker を使うことで、プッシュ通知やバックグラウンド同期の API も利用可能になります。</li> + <li>Chrome Worker は Firefox 上でのみ使える Worker です。アドオンの開発時、拡張機能で Web Workers を使いたいとき、または Worker の中で <a href="/ja/js-ctypes">js-ctypes</a> を使いたいときに用いることが出来ます。詳しくは {{DOMxRef("ChromeWorker")}} を参照してください。</li> + <li><a href="/ja/docs/Web/API/Web_Audio_API#Audio_Workers">Audio Worker</a> は、音声処理を Worker のコンテキスト内でスクリプトで直接実行する能力を提供します。</li> +</ul> + +<div class="note"> +<p><strong>メモ</strong>: <a href="https://html.spec.whatwg.org/multipage/workers.html#runtime-script-errors-2">Web Worker の仕様</a>にあるように、Worker のエラーイベントはバブルするべきではありません (see {{bug(1188141)}}。これは Firefox 42 で実装されました。</p> + +<p> </p> +</div> + +<h2 id="Web_Worker_interfaces" name="Web_Worker_interfaces">Web Worker インターフェイス</h2> + +<dl> + <dt>{{DOMxRef("AbstractWorker")}}</dt> + <dd>{{DOMxRef("Worker")}} や {{DOMxRef("SharedWorker")}} など、すべての Worker に共通な抽象オブジェクトです。</dd> + <dt>{{DOMxRef("Worker")}}</dt> + <dd>実行している Worker のスレッドを表します。実行している Worker のコードへメッセージを送る際に用います。</dd> + <dt>{{DOMxRef("WorkerLocation")}}</dt> + <dd>{{DOMxRef("Worker")}} で実行されるスクリプトの絶対位置を定義します。</dd> + <dt>{{DOMxRef("SharedWorker")}}</dt> + <dd>複数のウィンドウ、 iframe、ワーカーなどいくつかの{{glossary("browsing context", "閲覧コンテキスト")}}から「アクセス可能な」具体的な種類の Worker を表します。</dd> + <dt>{{DOMxRef("WorkerGlobalScope")}}</dt> + <dd>{{DOMxRef("Window")}} のように通常のウェブコンテンツと同じ動作をする Worker の一般的なスコープを表します。これと異なる種類の Worker は、このインタフェースに独自の機能をいくつか加えたスコープを持ちます。</dd> + <dt>{{DOMxRef("DedicatedWorkerGlobalScope")}}</dt> + <dd>Dedicated Worker のスコープを表します。 {{DOMxRef("WorkerGlobalScope")}} を継承しており、独自の機能がいくつか加えられています。</dd> + <dt>{{DOMxRef("SharedWorkerGlobalScope")}}</dt> + <dd>Shared Worker のスコープを表します。 {{DOMxRef("WorkerGlobalScope")}} を継承しており、独自の機能がいくつか加えられています。</dd> + <dt>{{DOMxRef("WorkerNavigator")}}</dt> + <dd>ユーザエージェント (クライアント) に関する識別名と状態を表します。</dd> +</dl> + +<h2 id="Examples" name="Examples">例</h2> + +<p>簡単なデモと基本的な使い方は以下を参照してください。</p> + +<ul> + <li><a href="https://github.com/mdn/simple-web-worker">Basic dedicated worker example</a> (<a href="http://mdn.github.io/simple-web-worker/">run dedicated worker</a>).</li> + <li><a href="https://github.com/mdn/simple-shared-worker">Basic shared worker example</a> (<a href="http://mdn.github.io/simple-shared-worker/">run shared worker</a>).</li> +</ul> + +<p>このデモの動く仕組みを詳しく知りたい場合は <a href="/ja/docs/Web/API/Web_Workers_API/Using_web_workers">Web Worker を使用する</a>を参照してください。</p> + +<h2 id="Specifications" name="Specifications">仕様</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様書</th> + <th scope="col">状態</th> + <th scope="col">備考</th> + </tr> + <tr> + <td>{{SpecName("HTML WHATWG", "workers.html#workers", "Web Workers")}}</td> + <td>{{Spec2("HTML WHATWG")}}</td> + <td>初回定義</td> + </tr> + </tbody> +</table> + +<h2 id="あわせて参照">あわせて参照</h2> + +<ul> + <li><a href="/ja/docs/Web/API/Web_Workers_API/Using_web_workers">Web Worker を使用する</a></li> + <li><a href="/ja/docs/Web/API/Worker">Worker インターフェイス</a></li> + <li><a href="/ja/docs/Web/API/SharedWorker">SharedWorker インターフェイス</a></li> + <li><a href="/ja/docs/Web/API/ServiceWorker_API">ServiceWorker API</a></li> + <li><a href="/ja/docs/Web/API/Worker/Functions_and_classes_available_to_workers">Web Workers が使用できる関数とクラス</a></li> + <li><a href="/ja/docs/Web/API/Web_Workers_API/Advanced_concepts_and_examples">Web Worker を使用する</a></li> + <li><a href="/ja/docs/Web/API/ChromeWorker">ChromeWorker</a>: Worker の特権/クロームコードでの使用</li> +</ul> diff --git a/files/ja/web/api/web_workers_api/structured_clone_algorithm/index.html b/files/ja/web/api/web_workers_api/structured_clone_algorithm/index.html new file mode 100644 index 0000000000..0be43a0cf7 --- /dev/null +++ b/files/ja/web/api/web_workers_api/structured_clone_algorithm/index.html @@ -0,0 +1,112 @@ +--- +title: 構造化複製アルゴリズム +slug: Web/API/Web_Workers_API/Structured_clone_algorithm +translation_of: Web/API/Web_Workers_API/Structured_clone_algorithm +--- +<p><strong>構造化複製アルゴリズム </strong>は複雑な JavaScript オブジェクトをコピーするためのアルゴリズムです。これは {{domxref("Worker.postMessage()", "postMessage()")}} を介して <a href="/en-US/docs/Web/API/Worker">Worker</a> と送受信するとき、<a href="/en-US/docs/Glossary/IndexedDB">IndexedDB</a> にオブジェクトを格納するとき、<a href="https://wiki.developer.mozilla.org/ja/docs/Web/API/Web_Workers_API/Structured_clone_algorithm$edit#See_Also">他の API</a> のためにオブジェクトをコピーするときなど、データ転送時に内部で用いられています。無限ループを避けるため、以前にアクセスした参照のマップを保持しながら、入力オブジェクトを再帰処理することで複製していきます。</p> + +<h2 id="構造化複製で動作しないもの">構造化複製で動作しないもの</h2> + +<ul> + <li><a href="/en/JavaScript/Reference/Global_Objects/Function" title="en/JavaScript/Reference/Global Objects/Function"><code>Function</code></a> オブジェクトは構造化複製アルゴリズムでは複製されません。複製しようとすると <code>DATA_CLONE_ERR</code> 例外が送出されます。</li> + <li>DOM ノードを複製するときも同様に <code>DATA_CLONE_ERR</code> 例外が送出されます。</li> + <li>以下に挙げるオブジェクトのパラメーターは保持されません。 + <ul> + <li><a href="/en/JavaScript/Reference/Global_Objects/RegExp" title="en/JavaScript/Reference/Global Objects/regexp"><code>RegExp</code></a> オブジェクトの <code>lastIndex</code> フィールドは保持されません。</li> + <li>プロパティ記述子、セッター、ゲッター (もしくは同様のメタデータ系機能) は複製されません。たとえば、オブジェクトに <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor">プロパティ記述子</a> を使用して読み取り専用にしている場合でも、複製したものではデフォルトの条件である読み取り/書き込みに変わります。</li> + <li>プロトタイプチェーンは探索、複製されません。</li> + </ul> + </li> +</ul> + +<div class="blockIndicator note"> +<p><strong>メモ</strong>: ネイティブの <a href="/en/JavaScript/Reference/Global_Objects/Error" title="en/JavaScript/Reference/Global Objects/Error"><code>Error</code></a> 型は Chrome では複製できます。Firefox は <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1556604">対応中</a> です。</p> +</div> + +<h2 id="サポート済みの型">サポート済みの型</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">オブジェクトの型</th> + <th scope="col">備考</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Data_structures#Primitive_values">すべてのプリミティブ型</a></td> + <td>symbol を除く</td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean">Boolean</a> オブジェクト</td> + <td></td> + </tr> + <tr> + <td><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/String">String</a> オブジェクト</td> + <td></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a></td> + <td></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp">RegExp</a></td> + <td><code>lastIndex</code> フィールドは保持されません。</td> + </tr> + <tr> + <td>{{ domxref("Blob") }}</td> + <td></td> + </tr> + <tr> + <td>{{ domxref("File") }}</td> + <td></td> + </tr> + <tr> + <td>{{ domxref("FileList") }}</td> + <td></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/API/ArrayBuffer">ArrayBuffer</a></td> + <td></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/API/ArrayBufferView">ArrayBufferView</a></td> + <td>他の <a href="/en-US/docs/Web/JavaScript/Typed_arrays">型付き配列</a> を含む</td> + </tr> + <tr> + <td>{{ domxref("ImageBitmap") }}</td> + <td></td> + </tr> + <tr> + <td>{{ domxref("ImageData") }}</td> + <td></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></td> + <td></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></td> + <td>これはプレーンオブジェクト (オブジェクトリテラルなど) <strong>のみ </strong>を含みます</td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map">Map</a></td> + <td></td> + </tr> + <tr> + <td><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set">Set</a></td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="関連情報">関連情報</h2> + +<ul> + <li><a href="http://www.w3.org/TR/html5/infrastructure.html#safe-passing-of-structured-data" title="http://www.w3.org/TR/html5/common-dom-interfaces.html#safe-passing-of-structured-data">HTML Specification: Safe passing of structured data</a></li> + <li>{{ domxref("window.history") }}</li> + <li>{{ domxref("window.postMessage()") }}</li> + <li><a href="/en-US/docs/Web/API/Web_Workers_API">Web Workers</a></li> + <li><a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a></li> + <li><a href="/en-US/docs/Components.utils.cloneInto">Components.utils.cloneInto</a></li> +</ul> diff --git a/files/ja/web/api/web_workers_api/using_web_workers/index.html b/files/ja/web/api/web_workers_api/using_web_workers/index.html new file mode 100644 index 0000000000..e7719ecabe --- /dev/null +++ b/files/ja/web/api/web_workers_api/using_web_workers/index.html @@ -0,0 +1,744 @@ +--- +title: Web Worker の使用 +slug: Web/API/Web_Workers_API/Using_web_workers +tags: + - Advanced + - Firefox + - Guide + - HTML5 + - JavaScript + - Workers +translation_of: Web/API/Web_Workers_API/Using_web_workers +--- +<div>{{DefaultAPISidebar("Web Workers API")}}</div> + +<p>Web Worker は、ウェブコンテンツがスクリプトをバックグラウンドのスレッドで実行するためのシンプルな手段です。 Worker スレッドは、ユーザーインターフェイスを妨げることなくタスクを実行できます。加えて、それらは (<code>responseXML</code> 属性や <code>channel</code> 属性は常に null ですが) <code><a href="/ja/docs/nsIXMLHttpRequest" title="XMLHttpRequest">XMLHttpRequest</a></code> を使用して入出力を行うこともできます。生成された Worker は、生成元が指定したイベントハンドラーへメッセージを送ることにより JavaScript コードへメッセージを送ることができます (その逆も可能です)。本記事では、 Web Workers の使い方を詳しく紹介します。</p> + +<h2 id="Web_Workers_API" name="Web_Workers_API">Web Workers API</h2> + +<p>Worker はコンストラクター (例えば {{domxref("Worker.Worker", "Worker()")}}) を使用して生成されたオブジェクトであり、名前付きの JavaScript ファイル (このファイルは Worker スレッドで実行するコードを持ちます) を実行します。また Worker は、カレントの {{domxref("window")}} とは異なるグローバルコンテキストで実行されます。従って、{{domxref("Worker")}} 内でカレントのグローバルスコープを取得するために ({{domxref("window.self","self")}} の代わりに) {{domxref("window")}} ショートカットを使用しても、エラーが返ります。</p> + +<p>Worker のコンテキストは、Dedicated Workers (ひとつのスクリプトが利用する、標準的な Workers) の場合は {{domxref("DedicatedWorkerGlobalScope")}} オブジェクトで表します (Shared Workers の場合は {{domxref("SharedWorkerGlobalScope")}})。Dedicated Worker は、Worker を生成したスクリプトだけがアクセスできます。一方 Shared Worker は、複数のスクリプトからアクセスできます。</p> + +<div class="note"> +<p><strong>メモ</strong>: Worker のリファレンスドキュメントや追加のガイドについては <a href="/ja/docs/Web/API/Web_Workers_API">Web Workers API のトップページ</a>をご覧ください。</p> +</div> + +<p>Worker スレッドでは、いくつかの制限のもとでどのようなコードでも実行できます。例えば、Worker 内から直接 DOM を操作することはできません。また {{domxref("window")}} オブジェクトのデフォルトのメソッドやプロパティで、使用できないものがあります。それでも <a href="/ja/docs/WebSockets">WebSocket</a>、 <a href="/ja/docs/Web/API/IndexedDB_API">IndexedDB</a>、 Firefox OS 限定の <a href="/ja/docs/Web/API/Data_Store_API">Data Store API</a> といったデータストレージ機構など、<code>window</code> 配下にある多数のアイテムを使用できます。詳しくは <a href="/ja/docs/Web/API/Worker/Functions_and_classes_available_to_workers">Web Worker で使用できる関数やクラス</a> をご覧ください。</p> + +<p>メッセージシステムを使用して、Worker とメインスレッドの間でデータを送信します。どちらも <code>postMessage()</code> メソッドを使用してメッセージを送信して、<code>onmessage</code> イベントハンドラーによってメッセージに応答します (メッセージは {{event("Message")}} イベントの data 属性に収められます)。データは共有せず、コピーします。</p> + +<p>Worker は新たな Worker を作成できます。ただし、それらの Worker が親ページとして同じ生成元のもとに存在する場合に限ります。また、Worker はネットワーク I/O のために <a href="/ja/docs/DOM/XMLHttpRequest" title="XMLHttpRequest"><code>XMLHttpRequest</code></a> を使用できますが、例外として <code>XMLHttpRequest</code> の <code>responseXML</code> および <code>channel</code> 属性は常に <code>null</code> を返します。</p> + +<h2 id="Dedicated_workers" name="Dedicated_workers">Dedicated Worker</h2> + +<p>前述のとおり Dedicated Worker は、呼び出し元のスクリプトだけがアクセスできます。本章では<a class="external external-icon" href="https://github.com/mdn/simple-web-worker">基本的な Dedicated Worker のサンプル</a> JavaScript を見ていきます (<a class="external external-icon" href="http://mdn.github.io/simple-web-worker/">Dedicated Worker を実行する</a>)。このサンプルでは、乗算を行う 2 つの数値を入力できます。数値は Dedicated Worker に送られて乗算され、そしてページに返された計算結果を表示します。</p> + +<p>これはあまり面白みのないサンプルですが、基本的な Worker のコンセプトを紹介する間はシンプルに保とうと考えています。より高度な詳細情報は、本章の後半で扱います。</p> + +<h3 id="Worker_feature_detection" name="Worker_feature_detection">Worker 機能を検出する</h3> + +<p>エラー制御と後方互換性を向上させるため、以下のように Worker へアクセスするコードを包み込むとよいでしょう (<a href="https://github.com/mdn/simple-web-worker/blob/gh-pages/main.js">main.js</a>):</p> + +<pre class="brush: js notranslate">if (window.Worker) { + + ... + +}</pre> + +<h3 id="Spawning_a_dedicated_worker" name="Spawning_a_dedicated_worker">Dedicated Worker を生成する</h3> + +<p>新しい Worker は簡単に生成できます。必要なことは、Worker スレッドで実行するスクリプトの URI を指定した {{domxref("Worker.Worker", "Worker()")}} コンストラクターを呼び出すだけです (<a href="https://github.com/mdn/simple-web-worker/blob/gh-pages/main.js">main.js</a>):</p> + +<div style="overflow: hidden;"> +<pre class="brush: js notranslate">var myWorker = new Worker('worker.js'); +</pre> +</div> + +<h3 id="Sending_messages_to_and_from_a_dedicated_worker" name="Sending_messages_to_and_from_a_dedicated_worker">Dedicated Worker とメッセージをやりとりする</h3> + +<p>Worker のマジックは、{{domxref("Worker.postMessage", "postMessage()")}} メソッドと {{domxref("Worker.onmessage", "onmessage")}} イベントハンドラーによって実現します。Worker にメッセージを送りたいときは、以下のようにしてメッセージを送信します (<a href="https://github.com/mdn/simple-web-worker/blob/gh-pages/main.js">main.js</a>):</p> + +<pre class="brush: js notranslate">first.onchange = function() { + myWorker.postMessage([first.value,second.value]); + console.log('Message posted to worker'); +} + +second.onchange = function() { + myWorker.postMessage([first.value,second.value]); + console.log('Message posted to worker'); +}</pre> + +<p>変数 <code>first</code> および <code>second</code> で示される、2 つの {{htmlelement("input")}} 要素があります。どちらかの値が変わると、双方の値を配列として Worker へ送信するために <code>myWorker.postMessage([first.value,second.value])</code> を使用します。メッセージでは、おおむねどのようなものでも送信できます。</p> + +<p>Worker では以下のようにイベントハンドラーのブロックにコードを記述すると、メッセージを受け取ったときに応答できます (<a href="https://github.com/mdn/simple-web-worker/blob/gh-pages/worker.js">worker.js</a>):</p> + +<pre class="brush: js notranslate">onmessage = function(e) { + console.log('Message received from main script'); + var workerResult = 'Result: ' + (e.data[0] * e.data[1]); + console.log('Posting message back to main script'); + postMessage(workerResult); +}</pre> + +<p><code>onmessage</code> ハンドラにより、メッセージを受け取ったときになんらかののコードを実行できます。メッセージ自体は、<code>message</code> イベントの <code>data</code> 属性で手に入ります。サンプルコードでは2つの数値で乗算を行った後、再び <code>postMessage()</code> を使用して計算結果をメインスレッドに返しています。</p> + +<p>メインスレッドに戻ると再び <code>onmessage</code> を使用して、Worker から返されたメッセージに応答します:</p> + +<pre class="brush: js notranslate">myWorker.onmessage = function(e) { + result.textContent = e.data; + console.log('Message received from worker'); +}</pre> + +<p>ここではメッセージイベントからデータを取り出して、result の <code>textContent</code> へ格納しています。よって、ユーザは計算結果を参照できます。</p> + +<div class="note"><strong>メモ</strong>: メインのスクリプトスレッドで <code>onmessage</code> および <code>postMessage()</code> を使用するときは <code>Worker</code> オブジェクトに付随させなければなりませんが、 Worker 内ではそのようにする必要はありません。これは、 Worker 内ではそれ自身が実質的にグローバルスコープであるためです。</div> + +<div class="note"><strong>メモ</strong>: メッセージをメインスレッドと Worker の間でやりとりするとき、メッセージは共有せずに "伝送" (移動) します。詳しい解説は、{{anch("Transferring data to and from workers further details", "Worker との間のデータ転送: 詳細")}}をご覧ください。</div> + +<h3 id="Terminating_a_worker" name="Terminating_a_worker">Worker の終了</h3> + +<p>実行中の Worker を直ちに終了したい場合は、 Worker の <code>terminate()</code> メソッドを呼び出してください。</p> + +<pre class="brush: js notranslate">myWorker.terminate();</pre> + +<p>Worker スレッドは直ちに終了します。</p> + +<h3 id="Handling_errors" name="Handling_errors">エラーハンドリング</h3> + +<p>Worker で実行時エラーが発生すると、 <code>onerror</code> イベントハンドラーが呼び出されます。これは、 <code>ErrorEvent</code> インターフェイスを実装している <code>error</code> イベントを受け取ります。</p> + +<p>イベントはバブリングせず、またキャンセルすることができます。 Worker はエラーイベントの {{domxref("Event/preventDefault", "preventDefault()")}} メソッドを呼び出すことで、発生元の既定のアクションを抑制することができます。</p> + +<p>エラーイベントには、以下の重要な 3 つの項目があります。</p> + +<dl> + <dt><code>message</code></dt> + <dd>人間が読み取れるエラーメッセージです。</dd> + <dt><code>filename</code></dt> + <dd>エラーが発生したスクリプトのファイル名です。</dd> + <dt><code>lineno</code></dt> + <dd>スクリプトファイル内でエラーが発生した場所の行番号です。</dd> +</dl> + +<h3 id="Spawning_subworkers" name="Spawning_subworkers">サブ Worker の生成</h3> + +<p>必要であれば、 Worker がさらに Worker を生成することができます。いわゆるサブ Worker は、親ページと同じ生成元で提供しなければなりません。またサブ Worker 用の URI は、その所有ページではなく親 Worker の場所からの相対位置として分析されます。これは、 Worker の依存関係を追跡し続けることを容易にします。</p> + +<h3 id="Importing_scripts_and_libraries" name="Importing_scripts_and_libraries">スクリプトやライブラリのインポート</h3> + +<p>Worker スレッドはグローバル関数や、スクリプトをインポートするための <code>importScripts()</code> にアクセスできます。これはインポートするリソースの URI を 0 個以上、引数として受け入れます。以下のサンプルはすべて有効です。</p> + +<pre class="brush: js notranslate">importScripts(); /* 何もインポートしない */ +importScripts('foo.js'); /* "foo.js" をインポート */ +importScripts('foo.js', 'bar.js'); /* 2 つのスクリプトをインポート */ +importScripts('//example.com/hello.js'); /* 他のオリジンのスクリプトをインポートすることができる */</pre> + +<p>ブラウザーはそれぞれのスクリプトを読み込み、実行します。 Worker は各スクリプトのグローバルオブジェクトを使用できます。スクリプトを読み込むことができない場合は <code>NETWORK_ERROR</code> を発生させて、それ以降のコードを実行しません。それでも、すでに実行されたコード ({{domxref("window.setTimeout()")}} で繰り延べされているコードを含みます) は動作します。<code>importScripts()</code> メソッドより<strong>後方</strong>にある関数の宣言は、常にコードの残りの部分より先に評価されることから、同様に保持されます。</p> + +<div class="note"><strong>注記</strong>: スクリプトは順不同にダウンロードされますが、実行は <code>importScripts()</code> に渡したファイル名の順に行います。これは同期的に行われます。すべてのスクリプトの読み込みと実行が行われるまで <code>importScripts()</code> から戻りません。</div> + +<h2 id="Shared_workers" name="Shared_workers">Shared Worker</h2> + +<p>Shared Worker は、生成元が同一であれば (異なる window、iframe、Worker からであっても) 複数のスクリプトからアクセスできます。本章では<a class="external external-icon" href="https://github.com/mdn/simple-shared-worker">基本的な Shared Worker のサンプル</a> JavaScript を見ていきます (<a class="external external-icon" href="https://mdn.github.io/simple-shared-worker/">Shared Worker を実行する</a>)。こちらは Dedicated Worker のサンプルと似ていますが、<em>2 つの数値で乗算を行う</em>スクリプトと<em>数値を 2 乗する</em>スクリプトという、別々のスクリプトファイルが扱う 2 つの関数を使用できる点が異なります。どちらのスクリプトも同じ Worker を使用して、実際に必要な計算を行います。</p> + +<p>ここでは、 Dedicated Worker と Shared Worker の違いについて注目します。このサンプルでは 2 つの HTML ページがあり、それぞれの JavaScript は同じひとつの Worker ファイルを使用するようになっています。</p> + +<div class="note"> +<p><strong>メモ</strong>: SharedWorker が複数の閲覧コンテキストからアクセスできる場合、すべての閲覧コンテキストはまったく同じオリジン (プロトコル、ホスト、ポート番号が同じ) です。</p> +</div> + +<div class="note"> +<p><strong>メモ</strong>: Firefox では、 Shared Worker はプライベートウィンドウとそれ以外に読み込まれた文書間で共有することができません ({{bug(1177621)}})。</p> +</div> + +<h3 id="Spawning_a_shared_worker" name="Spawning_a_shared_worker">Shared Worker の生成</h3> + +<p>新しい Shared Worker の生成方法は Dedicated Worker の場合とほとんど同じですが、コンストラクター名が異なります (<a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/index.html">index.html</a> および <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/index2.html">index2.html</a> をご覧ください)。それぞれのページで、以下のようなコードを使用して Worker を立ち上げます。</p> + +<pre class="brush: js notranslate">var myWorker = new SharedWorker('worker.js');</pre> + +<p>Shared Worker の大きな違いのひとつが、 <code>port</code> オブジェクトを通して通信しなければならないことです。スクリプトが Worker と通信するために使用できる、明示的なポートが開きます (これは、 Dedicated Worker でも暗黙的に開いています)。</p> + +<p>ポートへの接続は <code>onmessage</code> イベントハンドラーを使用して暗黙的に行うか、あるいはメッセージを送信する前に <code>start()</code> メソッドを使用して明示的に開始するかしなければなりません。 <code>start()</code> の呼び出しは、<code>addEventListener()</code> メソッドで <code>message</code> イベントを拾い上げる場合にのみ必要です。</p> + +<div class="note"> +<p>ポート接続を開始するために <code>start()</code> メソッドを使用するとき、双方向の通信が必要である場合は親スレッドと Worker の両方で呼び出さなければなりません。</p> +</div> + +<h3 id="Sending_messages_to_and_from_a_shared_worker" name="Sending_messages_to_and_from_a_shared_worker">Shared Worker とのメッセージのやりとり</h3> + +<p>前述のとおり Worker にメッセージを送信できるようになりましたが、<code>postMessage()</code> メソッドは port オブジェクトを通して呼び出さなければなりません (繰り返しますが、同様の構造が <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/multiply.js">multiply.js</a> および <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/square.js">square.js</a> に存在します)。</p> + +<pre class="brush: js notranslate">squareNumber.onchange = function() { + myWorker.port.postMessage([squareNumber.value,squareNumber.value]); + console.log('Message posted to worker'); +}</pre> + +<p>Worker に移ります。こちらは若干複雑さが増しています (<a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/worker.js">worker.js</a>):</p> + +<pre class="brush: js notranslate">onconnect = function(e) { + var port = e.ports[0]; + + port.onmessage = function(e) { + var workerResult = 'Result: ' + (e.data[0] * e.data[1]); + port.postMessage(workerResult); + } +}</pre> + +<p>始めに、ポートへの接続が発生したとき (すなわち、親スレッドで <code>onmessage</code> イベントをセットアップしたときや親スレッドで <code>start()</code> メソッドを明示的に呼び出したとき) にコードを実行するため <code>onconnect</code> ハンドラを使用します。</p> + +<p>イベントオブジェクトの <code>ports</code> 属性を使用してポートを取り出し、変数に格納します。</p> + +<p>次に、計算を実行して結果をメインスレッドに返すため、ポートの <code>onmessage</code> ハンドラを使用します。Worker スレッドで <code>onmessage</code> ハンドラをセットアップすると、親スレッドに戻すポート接続を暗黙的に開きます。従って、実際は前述のとおり <code>port.start()</code> を呼び出す必要はありません。</p> + +<p>最後に、メインスレッドに戻ってメッセージを扱います (繰り返しますが、同様の構造が <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/multiply.js">multiply.js</a> および <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/square.js">square.js</a> に存在します)。</p> + +<pre class="brush: js notranslate">myWorker.port.onmessage = function(e) { + result2.textContent = e.data; + console.log('Message received from worker'); +}</pre> + +<p>ポートを通して Worker からメッセージが戻ったときは、結果のデータ型を確認してから適切なパラグラフに計算結果を挿入します。</p> + +<h2 id="About_thread_safety" name="About_thread_safety">スレッドセーフについて</h2> + +<p>{{domxref("Worker")}} インターフェイスは実際の OS レベルのスレッドを生成しますので注意深いプログラマは、気をつけなければ同時実行によって、コードにおいて "興味深い" 効果を引き起こす可能性があると懸念するかもしれません。</p> + +<p>しかし Web Worker は他のスレッドとの通信ポイントが注意深く制御されていますので、実際は同時実行による問題を引き起こすことが非常に困難です。スレッドセーフではないコンポーネントや DOM にはアクセスできません。また、スレッド内外のデータはシリアライズしたオブジェクトを通して渡さなければなりません。よって、コードで問題を起こすことはとても難しいのです。</p> + +<h2 id="Content_security_policy" name="Content_security_policy">コンテンツセキュリティポリシー</h2> + +<p>Worker は、自分を生成した文書から区別された独自の実行コンテキストを持っているとみなされます。このため、一般に、自分を生成した文書 (または親 Worker) の<a href="/ja/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy">コンテンツセキュリティポリシー</a>では管理されません。そのため例えば、文書が次のヘッダー付きで読み込まれたと仮定します。</p> + +<pre class="notranslate">Content-Security-Policy: script-src 'self'</pre> + +<p>特に、これは {{jsxref("Global_Objects/eval", "eval()")}} を使用したスクリプトを防ぎます。しかし、スクリプトが Worker を構築した場合、 Worker のコンテキストで実行中のコードは <code>eval()</code> を使用することができます。<br> + <br> + Worker のコンテンツセキュリティポリシーを指定するには、 Worker スクリプト自身が配信されたリクエストの <a href="/ja/docs/Web/HTTP/Headers/Content-Security-Policy">Content-Security-Policy</a> レスポンスヘッダーで設定してください。<br> + <br> + Worker スクリプトのオリジンがグローバルに一意な識別子である場合 (例えば、 URL が data や blob のスキームであった場合) は例外です。この場合、 Worker は文書の CSP またはそれを作成した Worker を継承します。</p> + +<h2 id="Transferring_data_to_and_from_workers_further_details" name="Transferring_data_to_and_from_workers_further_details">Worker とのデータ伝送の詳細</h2> + +<p>メインページと Worker との間で送られるメッセージは、共有されるのではなく<strong>コピーされます</strong>。オブジェクトは Worker に渡している間シリアライズされ、その後戻されたときにシリアライズが解除されます。ページと Worker は<strong>同一のインスタンスを共有しません</strong>ので、結果として双方に<strong>複製</strong>が作られます。ほとんどのブラウザーはこの機能を <a href="/ja/docs/DOM/The_structured_clone_algorithm" title="The structured clone algorithm">structured cloning</a> として実装しています。</p> + +<p>これを説明するため、 <code>worker</code> からメインページおよびその逆の移動において<em>共有されず複製される</em>値の動作をシミュレーションする、教育的な用途の関数 <code>emulateMessage()</code> を作成しましょう:</p> + +<pre class="brush: js notranslate">function emulateMessage(vVal) { + return eval('(' + JSON.stringify(vVal) + ')'); +} + +// テスト + +// テスト #1 +var example1 = new Number(3); +console.log(typeof example1); // object +console.log(typeof emulateMessage(example1)); // number + +// テスト #2 +var example2 = true; +console.log(typeof example2); // boolean +console.log(typeof emulateMessage(example2)); // boolean + +// テスト #3 +var example3 = new String('Hello World'); +console.log(typeof example3); // object +console.log(typeof emulateMessage(example3)); // string + +// テスト #4 +var example4 = { + 'name': 'John Smith', + "age": 43 +}; +console.log(typeof example4); // object +console.log(typeof emulateMessage(example4)); // object + +// テスト #5 +function Animal(sType, nAge) { + this.type = sType; + this.age = nAge; +} +var example5 = new Animal('Cat', 3); +alert(example5.constructor); // Animal +alert(emulateMessage(example5).constructor); // Object</pre> + +<p>共有されず複製される値を<em>メッセージ</em>と呼びます。おわかりかと思いますが<em>メッセージ</em>は <code>postMessage()</code> を使用してメインスレッドへ、またはメインスレッドから送信でき、また <code>message</code> イベントの {{domxref("MessageEvent.data", "data")}} 属性に、Worker から返されたデータが含まれます。</p> + +<p><strong>example.html</strong> (メインページ)</p> + +<pre class="brush: js notranslate">var myWorker = new Worker('my_task.js'); + +myWorker.onmessage = function(oEvent) { + console.log('Worker said : ' + oEvent.data); +}; + +myWorker.postMessage('ali');</pre> + +<p><strong>my_task.js</strong> (Worker)</p> + +<pre class="brush: js notranslate">postMessage("I\'m working before postMessage(\'ali\')."); + +onmessage = function(oEvent) { + postMessage('Hi ' + oEvent.data); +};</pre> + +<p><a href="/ja/docs/Web/Guide/API/DOM/The_structured_clone_algorithm">structured cloning</a> アルゴリズムは JSON や、循環参照など JSON ではできないいくつかのものを受け入れることができます。</p> + +<h3 id="Passing_data_examples" name="Passing_data_examples">データ引き渡しのサンプル</h3> + +<h4 id="Example_1_Advanced_passing_JSON_Data_and_creating_a_switching_system" name="Example_1_Advanced_passing_JSON_Data_and_creating_a_switching_system">例 #1: 高度な JSON データ渡しと切り替えシステムの作成</h4> + +<p>もしいくつかの複雑なデータを渡さなければならず、メインページとWorkerの両方で多くの異なる関数を呼び出さなければならない場合、すべてをまとめてグループにするシステムを作ることができます。</p> + +<p>はじめに、WorkerのURL、デフォルトのリスナー、エラーハンドラーを持つQueryableWorkerクラスを作ります。このクラスはリスナーのリストを記録し、Workerとのコミュニケーションに役立ちます。</p> + +<pre class="brush: js notranslate">function QueryableWorker(url, defaultListener, onError) { + var instance = this, + worker = new Worker(url), + listeners = {}; + + this.defaultListener = defaultListener || function() {}; + + if (onError) {worker.onerror = onError;} + + this.postMessage = function(message) { + worker.postMessage(message); + } + + this.terminate = function() { + worker.terminate(); + } +}</pre> + +<p>そして、リスナーを追加 / 削除する方法を追加します。</p> + +<pre class="brush: js notranslate">this.addListeners = function(name, listener) { + listeners[name] = listener; +} + +this.removeListeners = function(name) { + delete listeners[name]; +}</pre> + +<p>ここでは、説明のためにWorkerに 2つの簡単な操作をさせてみましょう。2つの数値の差を取得することと、3秒後にアラートを出すことです。これを実現するために、まず最初に<code>sendQuery</code>メソッドを実装します。これは、Workerが実際に対応するメソッドを持っているかどうかを問い合わせるものです。</p> + +<pre class="brush: js notranslate">/* + This functions takes at least one argument, the method name we want to query. + Then we can pass in the arguments that the method needs. + */ +this.sendQuery = function() { + if (arguments.length < 1) { + throw new TypeError('QueryableWorker.sendQuery takes at least one argument'); + return; + } + worker.postMessage({ + 'queryMethod': arguments[0], + 'queryArguments': Array.prototype.slice.call(arguments, 1) + }); +}</pre> + +<p>QueryableWorkerは<code>onmessage</code>メソッドで終了します。ワーカーがクエリに対応するメソッドを持っている場合、対応するリスナーの名前と必要な引数を返すはずです。</p> + +<pre class="brush: js notranslate">worker.onmessage = function(event) { + if (event.data instanceof Object && + event.data.hasOwnProperty('queryMethodListener') && + event.data.hasOwnProperty('queryMethodArguments')) { + listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments); + } else { + this.defaultListener.call(instance, event.data); + } +} +</pre> + +<p>それではWorkerに移りましょう。まず、2つの単純な操作を処理するためのメソッドを用意する必要があります。</p> + +<pre class="brush: js notranslate">var queryableFunctions = { + getDifference: function(a, b) { + reply('printStuff', a - b); + }, + waitSomeTime: function() { + setTimeout(function() { + reply('doAlert', 3, 'seconds'); + }, 3000); + } +} + +function reply() { + if (arguments.length < 1) { + throw new TypeError('reply - takes at least one argument'); + return; + } + postMessage({ + queryMethodListener: arguments[0], + queryMethodArguments: Array.prototype.slice.call(arguments, 1) + }); +} + +/* This method is called when main page calls QueryWorker's postMessage method directly*/ +function defaultReply(message) { + // do something +} +</pre> + +<p>そして、<code>onmessage</code>メソッドは簡単になりました。</p> + +<pre class="brush: js notranslate">onmessage = function(event) { + if (event.data instanceof Object && + event.data.hasOwnProperty('queryMethod') && + event.data.hasOwnProperty('queryMethodArguments')) { + queryableFunctions[event.data.queryMethod] + .apply(self, event.data.queryMethodArguments); + } else { + defaultReply(event.data); + } +} +</pre> + +<p>ここでは、完全な実装を紹介します。</p> + +<p><strong>example.html</strong> (メインページ)</p> + +<pre class="brush: html notranslate"><!doctype html> + <html> + <head> + <meta charset="UTF-8" /> + <title>MDN Example - Queryable worker</title> + <script type="text/javascript"> + /* + QueryableWorker instances methods: + * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function + * postMessage(string or JSON Data): see Worker.prototype.postMessage() + * terminate(): terminates the Worker + * addListener(name, function): adds a listener + * removeListener(name): removes a listener + QueryableWorker instances properties: + * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly + */ + function QueryableWorker(url, defaultListener, onError) { + var instance = this, + worker = new Worker(url), + listeners = {}; + + this.defaultListener = defaultListener || function() {}; + + if (onError) {worker.onerror = onError;} + + this.postMessage = function(message) { + worker.postMessage(message); + } + + this.terminate = function() { + worker.terminate(); + } + + this.addListener = function(name, listener) { + listeners[name] = listener; + } + + this.removeListener = function(name) { + delete listeners[name]; + } + + /* + This functions takes at least one argument, the method name we want to query. + Then we can pass in the arguments that the method needs. + */ + this.sendQuery = function() { + if (arguments.length < 1) { + throw new TypeError('QueryableWorker.sendQuery takes at least one argument'); + return; + } + worker.postMessage({ + 'queryMethod': arguments[0], + 'queryMethodArguments': Array.prototype.slice.call(arguments, 1) + }); + } + + worker.onmessage = function(event) { + if (event.data instanceof Object && + event.data.hasOwnProperty('queryMethodListener') && + event.data.hasOwnProperty('queryMethodArguments')) { + listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments); + } else { + this.defaultListener.call(instance, event.data); + } + } + } + + // 独自の「照会可能な」 worker + var myTask = new QueryableWorker('my_task.js'); + + // 独自の「リスナー」 + myTask.addListener('printStuff', function (result) { + document.getElementById('firstLink').parentNode.appendChild(document.createTextNode('The difference is ' + result + '!')); + }); + + myTask.addListener('doAlert', function (time, unit) { + alert('Worker waited for ' + time + ' ' + unit + ' :-)'); + }); +</script> +</head> +<body> + <ul> + <li><a id="firstLink" href="javascript:myTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li> + <li><a href="javascript:myTask.sendQuery('waitSomeTime');">Wait 3 seconds</a></li> + <li><a href="javascript:myTask.terminate();">terminate() the Worker</a></li> + </ul> +</body> +</html></pre> + +<p><strong>my_task.js</strong> (Worker)</p> + +<pre class="brush: js notranslate">var queryableFunctions = { + // 例 #1: 2 つの値の差を得る: + getDifference: function(nMinuend, nSubtrahend) { + reply('printStuff', nMinuend - nSubtrahend); + }, + // 例 #2: 3 秒待つ + waitSomeTime: function() { + setTimeout(function() { reply('doAlert', 3, 'seconds'); }, 3000); + } +}; + +// システム関数 + +function defaultReply(message) { + // メインページが queryableWorker.postMessage() メソッドを直接呼び出したときに限り実行される、デフォルトの PUBLIC 関数 + // 何らかの処理 +} + +function reply() { + if (arguments.length < 1) { throw new TypeError('reply - not enough arguments'); return; } + postMessage({ 'queryMethodListener': arguments[0], 'queryMethodArguments': Array.prototype.slice.call(arguments, 1) }); +} + +onmessage = function(oEvent) { + if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty('queryMethod') && oEvent.data.hasOwnProperty('queryMethodArguments')) { + queryableFunctions[oEvent.data.queryMethod].apply(self, oEvent.data.queryMethodArguments); + } else { + defaultReply(oEvent.data); + } +};</pre> + +<p>各メインページ→Worker、Worker→メインページのメッセージの内容を切り替えることができます。そして、プロパティ名「queryMethod」「queryMethodListeners」「queryMethodArguments」は、<code>QueryableWorker</code>とWorkerで一致していれば何でも構いません。</p> + +<h3 id="Passing_data_by_transferring_ownership_transferable_objects" name="Passing_data_by_transferring_ownership_(transferable_objects)">所有権の譲渡 (Transferable Objects) によるデータの引き渡し</h3> + +<p>Google Chrome 17 以降および Firefox 18 以降には、特定の種類のオブジェクト ({{domxref("Transferable")}} インターフェイスを実装するオブジェクトである Transferable Object) を高いパフォーマンスで Worker から、または Worker へ渡すための、追加の手段があります。Transferable Object はあるコンテキストから別のコンテキストへ、コピー操作なしに転送されます。これにより、大量のデータセットを送信する際のパフォーマンスが大きく向上します。C/C++ の経験者であれば、参照渡しと考えてください。しかし参照渡しとは異なり、転送されると元のコンテキストからその版が失われます。そしてその所有権は新しいコンテキストに譲渡されます。例えば {{domxref("ArrayBuffer")}} をメインアプリから Worker スクリプトへ転送するとき、元の {{domxref("ArrayBuffer")}} はクリアされて使用できなくなります。その内容物は (文字どおり) Worker コンテキストに{{原語併記("転送", "transfer")}}されます。</p> + +<pre class="brush: js notranslate">// 32MB の "file" を作成して埋めます。 +var uInt8Array = new Uint8Array(1024*1024*32); // 32MB +for (var i = 0; i < uInt8Array.length; ++i) { + uInt8Array[i] = i; +} + +worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]); +</pre> + +<div class="note"> +<p><strong>注記</strong>: Transferable Object、パフォーマンス、およびメソッドの機能検出について詳しくは、HTML5 Rocks の <a href="http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast">Transferable Objects: Lightning Fast!</a> をご覧ください。</p> +</div> + +<h2 id="Embedded_workers" name="Embedded_workers">埋め込み Worker</h2> + +<p>通常のスクリプトを {{HTMLElement("script")}} 要素で埋め込むように、 Worker のコードをウェブページに埋め込むための "公式な" 方法はありません。しかし <code>src</code> 属性を持たず、また実行可能な MIME タイプを示さない <code>type</code> 属性を持つ {{HTMLElement("script")}} 要素は、JavaScript が使用できるデータブロック要素であると判断されます。"データブロック" はほとんどのテキストデータを持つことができる、HTML5 の一般的な機能です。よって、以下の方法で Worker を埋め込むことができます:</p> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8" /> +<title>MDN Example - Embedded worker</title> +<script type="text/js-worker"> + // MIME タイプが text/js-worker であるため、このスクリプトは JS エンジンに解釈されません。 + var myVar = 'Hello World!'; + // worker の残りのコードをここに置きます。 +</script> +<script type="text/javascript"> + // MIME タイプが text/javascript であるため、このスクリプトは JS エンジンに解釈されます。 + function pageLog(sMsg) { + // fragment を使用: ブラウザーは 1 回だけレンダリング/リフローします。 + var oFragm = document.createDocumentFragment(); + oFragm.appendChild(document.createTextNode(sMsg)); + oFragm.appendChild(document.createElement('br')); + document.querySelector('#logDisplay').appendChild(oFragm); + } +</script> +<script type="text/js-worker"> + // MIME タイプが text/js-worker であるため、このスクリプトは JS エンジンに解釈されません。 + onmessage = function(oEvent) { + postMessage(myVar); + }; + // worker の残りのコードをここに置きます。 +</script> +<script type="text/javascript"> + // MIME タイプが text/javascript であるため、このスクリプトは JS エンジンに解釈されます。 + + // + // 以前は blob を構築していましたが、 + // 現在は Blob を使用します: + var blob = new Blob(Array.prototype.map.call(document.querySelectorAll('script[type=\'text\/js-worker\']'), function (oScript) { return oScript.textContent; }),{type: 'text/javascript'}); + + // すべての "text/js-worker" スクリプトを含む、新たな document.worker プロパティを生成します。 + document.worker = new Worker(window.URL.createObjectURL(blob)); + + document.worker.onmessage = function(oEvent) { + pageLog('Received: ' + oEvent.data); + }; + + // Worker を開始します。 + window.onload = function() { document.worker.postMessage(''); }; +</script> +</head> +<body><div id="logDisplay"></div></body> +</html></pre> + +<p>埋め込み Worker が、新たな独自の <code>document.worker</code> プロパティの入れ子になります。</p> + +<p>言うまでもなく、次の例のように、関数を Blob に変換して、その blob からオブジェクトの URL を生成することができます。</p> + +<pre class="brush: js notranslate">function fn2workerURL(fn) { + var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'}) + return URL.createObjectURL(blob) +}</pre> + +<h2 id="Further_examples" name="Further_examples">追加サンプル</h2> + +<p>ここでは Web Worker の使用方法について、さらにサンプルを示します。</p> + +<h3 id="Performing_computations_in_the_background" name="Performing_computations_in_the_background">バックグラウンドで演算を行う</h3> + +<p>Worker は主に、ユーザーインターフェイスのスレッドを妨げずに CPU 負荷が大きい演算を実行するために役立ちます。このサンプルでは、 Worker をフィボナッチ数の計算に使用します。</p> + +<h4 id="The_JavaScript_code" name="The_JavaScript_code">JavaScript コード</h4> + +<p>以下の JavaScript コードはファイル "fibonacci.js" に保存され、次章の HTML が参照します。</p> + +<pre class="brush: js notranslate">var results = []; + +function resultReceiver(event) { + results.push(parseInt(event.data)); + if (results.length == 2) { + postMessage(results[0] + results[1]); + } +} + +function errorReceiver(event) { + throw event.data; +} + +onmessage = function(event) { + var n = parseInt(event.data); + + if (n == 0 || n == 1) { + postMessage(n); + return; + } + + for (var i = 1; i <= 2; i++) { + var worker = new Worker('fibonacci.js'); + worker.onmessage = resultReceiver; + worker.onerror = errorReceiver; + worker.postMessage(n - i); + } + };</pre> + +<p>Worker は、Worker オブジェクトの <code>postMessage()</code> が呼び出されたときにメッセージを受け取る関数を <code>onmessage</code> プロパティに設定します (これは onmessage という名前のグローバル<em>変数</em>や<em>関数</em>を定義することとは違いますので注意してください。<code>var onmessage</code> や <code>function onmessage</code> はその名前でグローバルプロパティを定義しますが、Worker を生成したウェブページが送信したメッセージを受け取る関数を登録しません)。これは再帰的に開始して、計算の反復処理を行うために自身のコピーを生成します。</p> + +<h4 id="The_HTML_code" name="The_HTML_code">HTML コード</h4> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8" /> + <title>Test threads fibonacci</title> + </head> + <body> + + <div id="result"></div> + + <script language="javascript"> + + var worker = new Worker('fibonacci.js'); + + worker.onmessage = function(event) { + document.getElementById('result').textContent = event.data; + dump('Got: ' + event.data + '\n'); + }; + + worker.onerror = function(error) { + dump('Worker error: ' + error.message + '\n'); + throw error; + }; + + worker.postMessage('5'); + + </script> + </body> +</html> +</pre> + +<p>ウェブページは ID <code>result</code> を持つ <code>div</code> 要素を作成して、結果を表示するために使用します。そして、Worker を生成します。Worker を生成した後は、<code>onmessage</code> ハンドラを <code>div</code> 要素の内容物を指定することで結果を表示するように、また <code>onerror</code> ハンドラはエラーメッセージを<a href="/ja/docs/Debugging_JavaScript#dump()" title="Debugging JavaScript">ダンプ</a>するように設定します。</p> + +<p>最後に、 Worker を開始するためにメッセージを送信します。</p> + +<p><a href="https://mdn.github.io/fibonacci-worker/">この例のデモを試してください</a>。</p> + +<h3 id="Performing_web_IO_in_the_background" name="Performing_web_IO_in_the_background">バックグラウンドでのウェブ入出力の実行</h3> + +<p>このサンプルは、 <a href="/ja/docs/Using_workers_in_extensions" title="Using workers in extensions">Using workers in extensions</a> の記事に掲載しています。</p> + +<h3 id="Dividing_tasks_among_multiple_workers" name="Dividing_tasks_among_multiple_workers">複数の Worker にタスクを分割する</h3> + +<p>マルチコアのコンピュータが次第に一般化することで複数の Worker に複雑な計算処理を分割することが有用になり、それらのタスクを複数の CPU コアで実行することが可能になります。</p> + +<h2 id="Other_types_of_worker" name="Other_types_of_worker">その他の Worker</h2> + +<p>Dedicated Worker や Shared Worker に加えて、他の種類の Worker を使用できます:</p> + +<ul> + <li><a href="/ja/docs/Web/API/ServiceWorker_API">Service Worker</a> は本質的に、ウェブアプリケーション、ブラウザー、ネットワークの間 (可能であれば) でプロキシサーバーとして振る舞います。これは、例えば効果的なオフライン体験、ネットワークリクエストへの介入、ネットワークが利用可能かやサーバー上で更新された資源に応じて適切なアクションを行うなどを意図しています。また、プッシュ通知やバックグラウンド同期 API へのアクセスも可能です。</li> + <li>Chrome Worker は、アドオンを開発していて拡張機能で Worker の使用を望んでおり、また Worker で <a href="https://developer.mozilla.org/en/js-ctypes" title="js-ctypes">js-ctypes</a> にアクセスする場合に使用できる、 Firefox 限定の Worker です。詳しくは {{domxref("ChromeWorker")}} をご覧ください。</li> + <li><a href="/ja/docs/Web/API/Web_Audio_API#Audio_Workers">Audio Worker</a> は、Web Worker のコンテキスト内でスクリプトによるオーディオ処理を直接実行する機能を提供します。</li> +</ul> + +<h2 id="Functions_and_interfaces_available_in_workers" name="Functions_and_interfaces_available_in_workers">Worker で使用できる関数とインターフェイス</h2> + +<p>以下を含む、ほとんどの標準的な JavaScript 機能を Web Worker 内で使用できます:</p> + +<ul> + <li>{{domxref("Navigator")}}</li> + <li>{{domxref("XMLHttpRequest")}}</li> + <li>{{jsxref("Global_Objects/Array", "Array")}}、{{jsxref("Global_Objects/Date", "Date")}}、{{jsxref("Global_Objects/Math", "Math")}}、{{jsxref("Global_Objects/String", "String")}}</li> + <li>{{domxref("WindowTimers.setTimeout")}} および {{domxref("WindowTimers.setInterval")}}</li> +</ul> + +<p>Worker で<em>実行できない</em>ことは主に、親ページに直接影響を与えるものです。これは、 DOM の操作やページのオブジェクトを使用することを含みます。{{domxref("DedicatedWorkerGlobalScope.postMessage")}} を使用してメインスクリプトにメッセージを戻してから変更操作を行う形で、間接的に実行しなければなりません。</p> + +<div class="note"> +<p><strong>メモ</strong>: Worker で使用できる関数の完全なリストは、<a href="https://developer.mozilla.org/en-US/docs/Web/Reference/Functions_and_classes_available_to_workers" title="DOM/Worker/Functions available to workers">Worker で使用できる関数とインターフェイス</a>でご覧ください。</p> +</div> + +<h2 id="Specifications" name="Specifications">仕様書</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">仕様書</th> + <th scope="col">状態</th> + <th scope="col">備考</th> + </tr> + <tr> + <td>{{SpecName('HTML WHATWG', '#workers', 'Web workers')}}</td> + <td>{{Spec2('HTML WHATWG')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><code><a class="internal" href="/ja/docs/Web/API/Worker">Worker</a></code> インターフェイス</li> + <li><code><a class="internal" href="/ja/docs/Web/API/SharedWorker">SharedWorker</a></code> インターフェイス</li> + <li><a href="/ja/docs/Web/API/Worker/Functions_and_classes_available_to_workers">Worker で使用できる関数</a></li> +</ul> |