Un web worker è uno script JS che viene eseguito in background, separatamente dagli altri script, permettendoci di introdurre il threading nelle nostre app web. Sebbene non faccia parte delle specifiche HTML5, i web worker possono essere utilizzati con le app HTML5. In questo suggerimento, daremo un'occhiata a come usarli.
Nella terra di HTML5 abbiamo a disposizione alcune API molto interessanti. Alcuni di essi, come i Web Worker, sono utili per aumentare le prestazioni, il che è molto importante sia per le app che per i giochi. Ma come fanno i web worker ... bene, lavoro?
Ogni istanza di un web worker crea un altro thread, in cui viene eseguito il tuo JavaScript. Si istanzia uno in questo modo:
var worker = new Worker ('filename.js');
Qui, 'filename.js' è il nome del file che contiene il tuo script. Poiché i lavoratori sono ambienti individuali, non è possibile utilizzare il codice incorporato direttamente in HTML; è necessario utilizzare un file separato.
I lavoratori non hanno accesso alla pagina DOM o all'oggetto globale, quindi come fanno a comunicare con il sito? È semplice. Quando vuoi inviare alcuni dati dalla tua pagina a un lavoratore, invochi postMessage ()
.
Questo richiede un parametro: dati da inviare, che può essere una stringa o un oggetto parser JSON (il che significa che non è possibile passare funzioni o riferimenti circolari, o si otterrà un DOM_EXCEPTION
). Su alcuni browser c'è un problema con gli oggetti, quindi è sempre meglio analizzare manualmente l'oggetto con JSON.parse ()
quindi non devi preoccuparti di implementazioni incomplete.
Lo stesso vale se stai inviando dati da un lavoratore alla pagina: invoca postMessage ()
sopra se stesso
, che si riferisce all'ambito globale del lavoratore. (Lo fai all'interno del copione del lavoratore, ovviamente).
Quindi, per ricevere i dati devi allegare un onMessage
gestore di eventi. Ci sono due modi per farlo, proprio come con gli eventi regolari per gli elementi DOM; puoi assegnare direttamente qualche funzione a quella del lavoratore onMessage
proprietà, o è possibile utilizzare addEventListener ()
.
// Primo modo: worker.onmessage = function (e) console.log (e.data); // registra i dati passati // Secondo modo: worker.addEventListener ('message', function (e) console.log (e.data); // registra i dati passati);
È la tua scelta quale metodo usare. In entrambi i casi, il parametro della funzione sarà a evento
oggetto e i dati inviati dall'utente postMessage ()
sarà passato tramite il dati
proprietà di questo evento.
Ok, ma se dovessimo usare qualche libreria esterna? Non abbiamo accesso al DOM o all'ambito globale, quindi non possiamo semplicemente inserire lo script.
Ovviamente non è necessario: esiste una funzione per questo. È chiamato importScripts ()
e accetta uno o più argomenti: nomi di script da caricare all'interno dell'ambito del lavoratore. Dovresti essere consapevole che gli script passati in questa funzione sono caricati in un ordine casuale, ma verranno eseguiti come specificato e l'esecuzione dello script sarà sospesa fino a quando non saranno caricati.
importScripts ( 'one-lib.js'); // Carica uno script importScripts ('first-lib.js', 'second-lib.js', 'third-lib.js'); // Carica tre script
Puoi usare importScripts
ovunque nel codice, facilitando la creazione di richieste JSONP all'interno dei lavoratori, come faremo nel seguente esempio.
Giusto, quindi probabilmente vorrai vedere un operaio in azione. Invece di mostrare qualcosa di abbastanza inutile, come ottenere numeri primi o numeri di Fibonacci, ho deciso di creare qualcosa che forse userete dopo alcune modifiche.
Lo script di esempio (ho incluso solo il codice Worker, il resto è facile da fare) otterrà gli ultimi 100 tweet da @envatoactive (dobbiamo impostare il conteggio su 121 anziché su 100, poiché l'API di Tweeter invia meno tweet di richiesto - non chiedermi perché, non lo so).
Ecco il codice che andrebbe all'interno del vero file di script Web Worker:
// Funzione di supporto per l'elaborazione dei dati var process = function (data) // Iterate attraverso i dati; sappiamo che è un array, quindi è sicuro per (var i = 0, v; v = data [i]; i ++) // e passa il testo di Tweet alla pagina self.postMessage (text: v.text); // Al termine del lavoro, consenti alla pagina self.postMessage ("finished"); // Allega listener di eventi per gestire i messaggi self.addEventListener ('message', function (event) // Verifica se il comando inviato era 'start' // Non necessario qui, ma potrebbe essere utile in seguito if (event.data == "start") // Rispondi alla pagina in cui abbiamo iniziato il lavoro self.postMessage ("started"); // Core dello script, ottieni i Tweet // Il parametro callback specifica la funzione da eseguire dopo che la richiesta è stata eseguita // (Chiamiamo la funzione process (), definita sopra.) // Count deve essere 121 perché l'API Tweeter invia una quantità di dati inferiore a importScripts richiesti ("http://twitter.com/statuses/user_timeline/envatoactive. json? callback = process & count = 121 "););
Dovrebbe essere facile capire come tutto questo funzioni dai commenti. Ciò consente alla tua app di caricare tutti i tweet in background, utilizzando un thread separato.
Ora prova ad inserire il seguente codice equivalente, che non lo fa usa i web worker, invece, in testa a una pagina vuota e annota il ritardo. (È ancora piccolo, ma immagina se non ricevessi 100 ma 100.000 tweet):
Come puoi vedere, i web worker ti offrono un modo semplice per rimuovere il lag dalla tua GUI e spostare complicati calcoli o reti per separare i thread.
Spero che tu abbia imparato qualcosa di nuovo da questo articolo - forse userete i Lavoratori nel vostro prossimo progetto? In caso di domande o problemi, si prega di commentare qui sotto.