Решение html5rocks по встраиванию кода веб-работника в HTML довольно ужасно.
К тому же бланк экранированного JavaScript-as-a-string не лучше, не в последнюю очередь потому, что он усложняет рабочий процесс (компилятор Closure не может работать со строками).
Лично мне действительно нравятся методы toString, но @ dan-man ЭТО регулярное выражение!
Мой предпочтительный подход:
// 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 );
Поддержка - это пересечение этих трех таблиц:
Однако это не сработает для SharedWorker , поскольку URL-адрес должен точно соответствовать, даже если необязательный параметр name совпадает. Для SharedWorker вам понадобится отдельный файл JavaScript.
Обновление 2015 года - наступает особенность ServiceWorker
Теперь есть еще более мощный способ решения этой проблемы. Опять же, сохраните рабочий код как функцию (а не статическую строку) и преобразуйте ее с помощью .toString (), затем вставьте код в CacheStorage под выбранным статическим 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'}})
);
});
Есть два возможных отступления. ObjectURL, как описано выше, или, что более удобно, поместите настоящий файл JavaScript в /my_workers/worker1.js
Преимущества этого подхода:
- SharedWorkers также могут поддерживаться.
- Вкладки могут совместно использовать одну кэшированную копию по фиксированному адресу. Подход BLOB-объектов распространяет случайные объектные URL для каждой вкладки.