将Web Worker代码嵌入HTML的html5rocks解决方案相当糟糕。
一串转义的JavaScript字符串并不是更好,这不仅因为它使工作流程复杂(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()进行转换,然后将代码插入到您选择的静态URL下的CacheStorage中。
// 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方法会为每个选项卡扩散随机的objectURL。