在 HTML 中嵌入 web worker 代码的 html5rocks 解决方案相当糟糕。
一团转义的 JavaScript-as-a-string 也好不到哪里去,尤其是因为它使工作流程复杂化(闭包编译器不能对字符串进行操作)。
我个人非常喜欢 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 );
Support是这三个表的交集:
但是,这不适用于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。