Recherche…


Syntaxe

  • nouveau travailleur (fichier)
  • postMessage (données, transferts)
  • onmessage = function (message) {/ * ... * /}
  • onerror = function (message) {/ * ... * /}
  • mettre fin()

Remarques

  • Les employés de service ne sont activés que pour les sites Web hébergés via HTTPS.

Enregistrer un employé de service

// 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);
  });
}
  • Vous pouvez appeler register() à chaque chargement de page. Si le SW est déjà enregistré, le navigateur vous fournit l'instance en cours d'exécution
  • Le fichier SW peut être n'importe quel nom. sw.js est commun.
  • L'emplacement du fichier SW est important car il définit la portée du logiciel. Par exemple, un fichier SW dans /js/sw.js ne peut intercepter que les requêtes de fetch pour les fichiers commençant par /js/ . Pour cette raison, vous voyez généralement le fichier SW dans le répertoire de niveau supérieur du projet.

Web Worker

Un travailleur Web est un moyen simple d'exécuter des scripts dans les threads d'arrière-plan, car le thread de travail peut effectuer des tâches (y compris des tâches d'E / S à l'aide de xmlHttpRequest) sans interférer avec l'interface utilisateur. Une fois créé, un agent peut envoyer des messages pouvant être différents types de données (à l'exception des fonctions) au code JavaScript qui l'a créé en publiant des messages sur un gestionnaire d'événements spécifié par ce code (et inversement).

Les travailleurs peuvent être créés de plusieurs manières.

Le plus courant provient d'une simple URL:

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

Il est également possible de créer un Worker dynamiquement à partir d'une chaîne en utilisant 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);

La même méthode peut être combinée avec Function.toString() pour créer un travailleur à partir d'une fonction existante:

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

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

var webworker = new Worker(blobURL);

Un simple travailleur de service

main.js

Un travailleur de service est un travailleur piloté par des événements enregistré sur une origine et un chemin. Il se présente sous la forme d'un fichier JavaScript capable de contrôler la page Web / le site auquel il est associé, d'intercepter et de modifier les demandes de navigation et de ressources et de mettre en cache les ressources de manière très précise. (le plus évident étant lorsque le réseau n'est pas disponible.)

Source: MDN

Quelques choses:

  1. C'est un JavaScript Worker, donc il ne peut pas accéder directement au DOM
  2. C'est un proxy réseau programmable
  3. Il sera terminé lorsqu'il ne sera pas utilisé et redémarré dès qu'il sera nécessaire
  4. Un agent de maintenance a un cycle de vie complètement distinct de votre page Web.
  5. HTTPS est nécessaire

Ce code qui sera exécuté dans le contexte Document (ou) ce JavaScript sera inclus dans votre page via une <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

Ceci est le code du travailleur du service et est exécuté dans la portée globale de ServiceWorker .

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

Travailleurs Dédiés et Travailleurs Partagés

Travailleurs Dédiés

Un travailleur Web dédié n'est accessible que par le script qui l'a appelé.

Application principale:

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]);
});

Travailleurs partagés

Un travailleur partagé est accessible par plusieurs scripts, même s'ils sont accessibles par différentes fenêtres, iframes ou même par des employés.

Créer un worker partagé est très similaire à la création d'un worker dédié, mais au lieu de la communication directe entre le thread principal et le thread de travail, vous devrez communiquer via un objet port, c'est-à-dire qu'un port explicite doit être ouvert afin que plusieurs scripts puissent l'utiliser pour communiquer avec le travailleur partagé. (Notez que les employés dédiés le font implicitement)

Application principale

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

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

travailleur.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]);
    }
}

Notez que la configuration de ce gestionnaire de messages dans le thread de travail ouvre également implicitement la connexion du port au thread parent, de sorte que l'appel à port.start() n'est pas réellement nécessaire, comme indiqué ci-dessus.

Résilier un travailleur

Une fois que vous avez terminé avec un travailleur, vous devriez le terminer. Cela permet de libérer des ressources pour d'autres applications sur l'ordinateur de l'utilisateur.

Fil principal:

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

Remarque : La méthode de terminate n'est pas disponible pour les techniciens de maintenance. Il sera terminé lorsqu'il ne sera pas utilisé et redémarré dès que nécessaire.

Fil ouvrier:

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

Remplir votre cache

Une fois votre technicien de maintenance enregistré, le navigateur essaiera d'installer et d'activer ultérieurement l'agent de maintenance.

Installer un écouteur d'événement

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

Mise en cache

On peut utiliser cet événement d'installation renvoyé pour mettre en cache les ressources nécessaires pour exécuter l'application en mode hors connexion. L'exemple ci-dessous utilise l'API du cache pour faire la même chose.

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'
      ]);
    })
  );
});

Communiquer avec un travailleur Web

Puisque les travailleurs s'exécutent dans un thread séparé de celui qui les a créés, la communication doit avoir lieu via postMessage .

Remarque: en raison des différents préfixes d'exportation, certains navigateurs ont webkitPostMessage au lieu de postMessage . Vous devez remplacer postMessage pour vous assurer que les travailleurs "fonctionnent" (sans jeu de mots) dans la plupart des endroits possibles:

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

Depuis le thread principal (fenêtre parente):

// 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"]
});

Du travailleur, dans 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"
});

Vous pouvez également ajouter des écouteurs d'événement en utilisant onmessage :

Depuis le thread principal (fenêtre parente):

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

Du travailleur, dans 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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow