Szukaj…


Składnia

  • nowy pracownik (plik)
  • postMessage (dane, przelewy)
  • onmessage = funkcja (komunikat) {/ * ... * /}
  • onerror = funkcja (komunikat) {/ * ... * /}
  • zakończyć()

Uwagi

  • Pracownicy usług mają dostęp tylko do witryn obsługiwanych przez HTTPS.

Zarejestruj pracownika serwisu

// 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);
  });
}
  • Możesz wywołać register() przy każdym ładowaniu strony. Jeśli SW jest już zarejestrowany, przeglądarka udostępnia już uruchomioną instancję
  • Plik SW może mieć dowolną nazwę. sw.js jest powszechny.
  • Lokalizacja pliku SW jest ważna, ponieważ określa zakres SW. Na przykład plik SW w katalogu /js/sw.js może przechwytywać tylko żądania fetch plików rozpoczynających się od /js/ . Z tego powodu zwykle plik SW znajduje się w katalogu najwyższego poziomu projektu.

Pracownik sieciowy

Pracownik WWW jest prostym sposobem uruchamiania skryptów w wątkach w tle, ponieważ wątek roboczy może wykonywać zadania (w tym zadania we / wy za pomocą xmlHttpRequest) bez ingerencji w interfejs użytkownika. Po utworzeniu pracownik może wysyłać wiadomości, które mogą być różnymi typami danych (oprócz funkcji), do kodu JavaScript, który go utworzył, wysyłając wiadomości do procedury obsługi zdarzeń określonej przez ten kod (i odwrotnie).

Pracowników można tworzyć na kilka sposobów.

Najczęściej pochodzi z prostego adresu URL:

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

Możliwe jest także dynamiczne tworzenie URL.createObjectURL() z ciągu przy użyciu 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);

Tę samą metodę można połączyć z Function.toString() aby utworzyć pracownika z istniejącej funkcji:

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

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

var webworker = new Worker(blobURL);

Prosty pracownik serwisu

main.js

Pracownik usługi to pracownik sterowany zdarzeniem, zarejestrowany w odniesieniu do źródła i ścieżki. Przybiera postać pliku JavaScript, który może kontrolować stronę / stronę, z którą jest skojarzony, przechwytując i modyfikując żądania nawigacji i żądań zasobów oraz buforując zasoby w bardzo szczegółowy sposób, aby dać ci pełną kontrolę nad tym, jak aplikacja zachowuje się w określonych sytuacjach (najbardziej oczywistym z nich jest brak sieci).

Źródło: MDN

Kilka rzeczy:

  1. Jest to JavaScript Worker, więc nie ma bezpośredniego dostępu do DOM
  2. To programowalny serwer proxy sieci
  3. Zostanie zakończony, gdy nie będzie używany, i ponownie uruchomiony, gdy będzie następny potrzebny
  4. Pracownik serwisu ma cykl życia całkowicie niezależny od Twojej strony internetowej
  5. Potrzebny jest HTTPS

Ten kod, który zostanie wykonany w kontekście dokumentu, (lub) ten JavaScript zostanie zawarty na twojej stronie poprzez tag <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

Jest to kod pracownika usługi i jest wykonywany w globalnym zakresie usługi ServiceWorker .

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

Dedykowani pracownicy i współdzieleni pracownicy

Dedykowani pracownicy

Dedykowany pracownik sieciowy jest dostępny tylko dla skryptu, który go wywołał.

Główne zastosowanie:

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

Współdzieleni pracownicy

Współdzielony pracownik jest dostępny za pomocą wielu skryptów - nawet jeśli dostęp do nich mają różne okna, elementy iframe lub nawet pracownicy.

Tworzenie współużytkowanego procesu roboczego jest bardzo podobne do sposobu tworzenia dedykowanego, ale zamiast prostej komunikacji między głównym wątkiem a wątkiem roboczym będziesz musiał komunikować się za pośrednictwem obiektu portu, tj. Port jawny musi być otwierane, aby wiele skryptów mogło z niego korzystać do komunikowania się z udostępnionym pracownikiem. (Uwaga: oddani pracownicy robią to w sposób dorozumiany)

Główna aplikacja

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

Zauważ, że skonfigurowanie tej procedury obsługi komunikatów w wątku port.start() również domyślnie otwiera połączenie portu z powrotem do wątku nadrzędnego, więc wywołanie port.start() nie jest tak naprawdę potrzebne, jak wspomniano powyżej.

Zakończ pracownika

Kiedy skończysz z pracownikiem, powinieneś go rozwiązać. Pomaga to zwolnić zasoby dla innych aplikacji na komputerze użytkownika.

Główny wątek:

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

Uwaga : Metoda terminate nie jest dostępna dla pracowników serwisu. Zostanie zakończony, gdy nie będzie używany, i ponownie uruchomiony, gdy będzie następny potrzebny.

Wątek pracownika:

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

Zapełnianie pamięci podręcznej

Po zarejestrowaniu pracownika usługi przeglądarka spróbuje zainstalować, a następnie aktywuje pracownika usługi.

Zainstaluj detektor zdarzeń

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

Buforowanie

Można użyć tego zdarzenia instalacji zwróconego do buforowania zasobów potrzebnych do uruchomienia aplikacji w trybie offline. Poniższy przykład używa interfejsu API pamięci podręcznej, aby zrobić to samo.

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

Komunikacja z pracownikiem sieciowym

Ponieważ pracownicy działają w innym wątku niż ten, który je utworzył, komunikacja musi odbywać się za pośrednictwem postMessage .

Uwaga: Z powodu różnych prefiksów eksportu niektóre przeglądarki mają webkitPostMessage zamiast postMessage . Powinieneś przesłonić postMessage aby upewnić się, że pracownicy „pracują” (bez zamierzonej gry słów) w jak największej liczbie miejsc:

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

Z głównego wątku (okno nadrzędne):

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

Od pracownika w 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"
});

Możesz również dodać detektory zdarzeń za pomocą onmessage :

Z głównego wątku (okno nadrzędne):

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

Od pracownika w 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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow