Rozwiązanie HTML5rocks polegające na osadzaniu kodu roboczego w HTML jest dość okropne.
A kropla uciekającego kodu JavaScript jako ciąg znaków nie jest lepsza, zwłaszcza dlatego, że komplikuje przepływ pracy (kompilator Closure nie może działać na ciągach znaków).
Osobiście bardzo lubię metody toString, ale @ dan-man TO wyrażenie regularne!
Moje preferowane podejście:
// 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 );
Wsparcie to przecięcie tych trzech tabel:
Nie będzie to jednak działać dla SharedWorker , ponieważ adres URL musi być dokładnie zgodny, nawet jeśli opcjonalny parametr „name” pasuje. Dla SharedWorker potrzebujesz osobnego pliku JavaScript.
Aktualizacja 2015 - Nadchodzi osobliwość ServiceWorker
Teraz istnieje jeszcze skuteczniejszy sposób rozwiązania tego problemu. Ponownie przechowuj kod roboczy jako funkcję (zamiast ciągu statycznego) i konwertuj za pomocą .toString (), a następnie wstaw kod do CacheStorage pod wybranym statycznym adresem URL.
// 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'}})
);
});
Możliwe są dwa awarie. ObjectURL jak wyżej lub bardziej płynnie, umieść prawdziwy plik JavaScript na /my_workers/worker1.js
Zalety tego podejścia to:
- SharedWorkers może być również obsługiwany.
- Karty mogą udostępniać jedną kopię z pamięci podręcznej pod stałym adresem. Metoda BLOB namnaża losowe adresy URL obiektów dla każdej karty.