サーチ…


構文

  • 新しいワーカー(ファイル)
  • postMessage(データ、転送)
  • onmessage = function(メッセージ){/ * ... * /}
  • onerror = function(メッセージ){/ * ... * /}
  • terminate()

備考

  • サービスワーカーは、HTTPS経由で提供されるWebサイトに対してのみ有効です。

サービスワーカーを登録する

// Check if service worker is available. 
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js').then(function(registration) {
    console.log('SW registration succeeded with scope:', registration.scope);
  }).catch(function(e) {
    console.log('SW registration failed with error:', e);
  });
}
  • すべてのページ読み込み時にregister()を呼び出すことができます。 SWがすでに登録されている場合、ブラウザはすでに実行中のインスタンスを提供します
  • SWファイルには任意の名前を使用できます。 sw.jsは一般的です。
  • SWファイルの場所は、SWのスコープを定義するため重要です。たとえば、 /js/ /js/sw.jsにあるSWファイルは、 /js/で始まるファイルのfetch要求をインターセプトすることしかできません。このため、通常、プロジェクトの最上位ディレクトリにSWファイルが表示されます。

Webワーカー

ワーカースレッドは、ユーザーインターフェイスを妨げずにタスク(xmlHttpRequestを使用したI / Oタスクを含む)を実行できるため、バックグラウンドスレッドでスクリプトを実行する簡単な方法です。作成されると、ワーカーは、コードで指定されたイベントハンドラにメッセージをポストすることで、関数を除いた異なるデータ型(メッセージの関数を除く)のメッセージを作成したJavaScriptコードに送信できます。

労働者は、いくつかの方法で作成することができます。

最も一般的なのは単純なURLです:

var webworker = new Worker("./path/to/webworker.js");

また、 URL.createObjectURL()を使用して文字列からワーカーを動的に作成することもできます。

var workerData = "function someFunction() {}; console.log('More code');";

var blobURL = URL.createObjectURL(new Blob(["(" + workerData + ")"], { type: "text/javascript" }));

var webworker = new Worker(blobURL);

同じメソッドをFunction.toString()と組み合わせて、既存の関数からワーカーを作成することができます:

var workerFn = function() {
    console.log("I was run");
};

var blobURL = URL.createObjectURL(new Blob(["(" + workerFn.toString() + ")"], { type: "text/javascript" }));

var webworker = new Worker(blobURL);

シンプルなサービスワーカー

main.js

サービスワーカーは、起点とパスに登録されたイベントドリブンワーカーです。関連するWebページやサイトを制御したり、ナビゲーションやリソース要求を傍受したり変更したり、リソースを非常にきめ細かくキャッシングして、アプリが特定の状況でどのように動作するかを完全に制御できるようにするJavaScriptファイルの形式を取ります(最も明らかなのは、ネットワークが利用できない場合です)。

出典: MDN

少々:

  1. これはJavaScriptワーカーなので、DOMに直接アクセスすることはできません
  2. プログラム可能なネットワークプロキシです
  3. 使用されていないときは終了し、次に必要なときは再起動します
  4. サービスワーカーは、Webページとは完全に別のライフサイクルを持っています
  5. HTTPSが必要です

Documentコンテキストで実行されるこのコードは、(または)このJavaScriptは<script>タグを介してページに組み込まれます。

// we check if the browser supports ServiceWorkers
if ('serviceWorker' in navigator) {
  navigator
    .serviceWorker
    .register(
      // path to the service worker file
      'sw.js'
    )
    // the registration is async and it returns a promise
    .then(function (reg) {
      console.log('Registration Successful');
    });
}

sw.js

これはサービスワーカーコードであり、 ServiceWorkerグローバルスコープで実行されます。

self.addEventListener('fetch', function (event) {
  // do nothing here, just log all the network requests
  console.log(event.request.url);
});

専用労働者と共有労働者

専用労働者

専用のWebワーカーは、呼び出されたスクリプトによってのみアクセス可能です。

主な用途:

var worker = new Worker('worker.js');
worker.addEventListener('message', function(msg) {
    console.log('Result from the worker:', msg.data);
});
worker.postMessage([2,3]);

worker.js:

self.addEventListener('message', function(msg) {
    console.log('Worker received arguments:', msg.data);
    self.postMessage(msg.data[0] + msg.data[1]);
});

共有労働者

共有ワーカーは、異なるウィンドウ、iframe、または労働者によってアクセスされていても、複数のスクリプトでアクセスできます。

共有ワーカーを作成する方法は、専用スレッドを作成する方法と非常によく似ていますが、メインスレッドとワーカースレッドの間の直接通信の代わりに、ポートオブジェクト経由で通信する必要があります。複数のスクリプトがそれを使用して共有ワーカーと通信できるように、オープンされている必要があります。 (献身的な労働者がこれを暗にしていることに注意してください)

主な用途

var myWorker = new SharedWorker('worker.js');
myWorker.port.start();  // open the port connection

myWorker.port.postMessage([2,3]);

worker.js

self.port.start(); open the port connection to enable two-way communication

self.onconnect = function(e) {
    var port = e.ports[0];  // get the port

    port.onmessage = function(e) {
        console.log('Worker revceived arguemnts:', e.data);
        port.postMessage(e.data[0] + e.data[1]);
    }
}

このメッセージハンドラをワーカースレッドに設定すると、暗黙的にポート接続が親スレッドに戻されるため、 port.start()呼び出しは実際には必要ではありません。

労働者を解雇する

あなたが作業を終えたら、それを終了させるべきです。これにより、ユーザーのコンピュータ上の他のアプリケーションのリソースを解放できます。

メインスレッド:

// Terminate a worker from your application.
worker.terminate();

:サービスワーカーでは、 terminate方法は使用できません。使用されていないときは終了し、次に必要なときは再起動します。

ワーカースレッド:

// Have a worker terminate itself.
self.close();

キャッシュの設定

サービスワーカーが登録されると、ブラウザはサービスワーカーをインストールして後でアクティブにしようとします。

イベントリスナーをインストールする

this.addEventListener('install', function(event) {
    console.log('installed');
});

キャッシング

このインストールイベントを使用して、アプリケーションをオフラインで実行するために必要なアセットをキャッシュすることができます。以下の例では、キャッシュAPIを使用して同じことを行います。

this.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      return cache.addAll([
        /* Array of all the assets that needs to be cached */
        '/css/style.css',
        '/js/app.js',
        '/images/snowTroopers.jpg'
      ]);
    })
  );
});

Webワーカーとのコミュニケーション

ワーカーはそれを作成したスレッドとは別のスレッドで実行されるため、 postMessageを介して通信する必要があります。

注:異なるプレフィックスのため、いくつかのブラウザーにはwebkitPostMessageではなくpostMessageます。 postMessageをオーバーライドして、できるだけ多くの場所で作業者が作業するようにする必要があります。

worker.postMessage = (worker.webkitPostMessage || worker.postMessage);

メインスレッド(親ウィンドウ)から:

// Create a worker
var webworker = new Worker("./path/to/webworker.js");

// Send information to worker
webworker.postMessage("Sample message");

// Listen for messages from the worker
webworker.addEventListener("message", function(event) {
    // `event.data` contains the value or object sent from the worker
    console.log("Message from worker:", event.data); // ["foo", "bar", "baz"]
});

webworker.jsの作業者から:

// Send information to the main thread (parent window)
self.postMessage(["foo", "bar", "baz"]);

// Listen for messages from the main thread
self.addEventListener("message", function(event) {
    // `event.data` contains the value or object sent from main
    console.log("Message from parent:", event.data); // "Sample message"
});

また、 onmessageを使用してイベントリスナーを追加することもできます。

メインスレッド(親ウィンドウ)から:

webworker.onmessage = function(event) {
    console.log("Message from worker:", event.data); // ["foo", "bar", "baz"]
}

webworker.jsの作業者から:

self.onmessage = function(event) {
    console.log("Message from parent:", event.data); // "Sample message"
}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow