La soluzione html5rocks di incorporare il codice Web worker in HTML è abbastanza orribile.
E un blocco di JavaScript sfuggito a una stringa non è migliore, anche perché complica il flusso di lavoro (il compilatore di chiusura non può operare su stringhe).
Personalmente mi piacciono molto i metodi toString, ma @ dan-man CHE regex!
Il mio approccio preferito:
// Build a worker from an anonymous function body
var blobURL = URL.createObjectURL( new Blob([ '(',
function(){
//Long-running work here
}.toString(),
')()' ], { type: 'application/javascript' } ) ),
worker = new Worker( blobURL );
// Won't be needing this anymore
URL.revokeObjectURL( blobURL );
Il supporto è l'intersezione di queste tre tabelle:
Tuttavia, ciò non funzionerà per un SharedWorker , poiché l'URL deve corrispondere esattamente, anche se il parametro facoltativo "name" corrisponde. Per un SharedWorker, avrai bisogno di un file JavaScript separato.
Aggiornamento 2015 - Arriva la singolarità di ServiceWorker
Ora c'è un modo ancora più potente per risolvere questo problema. Ancora una volta, memorizza il codice di lavoro come una funzione (anziché una stringa statica) e converti utilizzando .toString (), quindi inserisci il codice in CacheStorage sotto un URL statico di tua scelta.
// Post code from window to ServiceWorker...
navigator.serviceWorker.controller.postMessage(
[ '/my_workers/worker1.js', '(' + workerFunction1.toString() + ')()' ]
);
// Insert via ServiceWorker.onmessage. Or directly once window.caches is exposed
caches.open( 'myCache' ).then( function( cache )
{
cache.put( '/my_workers/worker1.js',
new Response( workerScript, { headers: {'content-type':'application/javascript'}})
);
});
Esistono due possibili fallback. ObjectURL come sopra, o più facilmente, metti un vero file JavaScript in /my_workers/worker1.js
I vantaggi di questo approccio sono:
- SharedWorkers può anche essere supportato.
- Le schede possono condividere una singola copia memorizzata nella cache a un indirizzo fisso. L'approccio BLOB prolifera oggettiURL casuali per ogni scheda.