我想在线创建 Web Worker,而不是引用外部脚本(这样我就可以部署单个 HTML 页面,而不是 HTML 文件和 JS 文件)。我在网上使用 Blobs here 找到了一个很酷的方法,但由于某种原因我无法让它工作。我也注意到该文章评论部分的结果好坏参半。
我收到错误:
Failed to load resource: the server responded with a status of 404 (Not Found)
在线错误:localhost:63342/[object%20Worker]:1
我猜 Web Worker 并不是真正的问题,而是在创建临时 url 资源时?如果是这样我还想念什么?
这是我的代码,位于 HTML 文件的 script 标记中:
function createWorker(fn) {
var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
var url = window.URL.createObjectURL(blob);
return new Worker(url);
}
var generic = function(e) {
self.postMessage('in line web worker code');
};
var worker = createWorker(generic);
if (window.Worker) {
var getEquipmentW = new Worker(worker);
getEquipmentW.postMessage({
msg: 'hi'
});
getEquipmentW.onmessage = function (e) {
console.log(e.data);
};
}
我会回答我自己的问题,您可以在单独的
script
标签中包含 Web Worker。我相信脚本类型不是官方类型,因此此标记中的代码直到稍后才会被评估。它看起来像这样:
<script id="myWorkerCode" type="javascript/worker">
self.onmessage = function(e) {
const data = e.data
self.postMessage('received some data in worker thread');
};
</script>
然后,在需要工作人员的脚本中,创建一个 Blob 并将内容分配为“javascript”类型。使该 Blob 成为您可以输入到
Worker
构造函数中的 URL:
if(window.Worker) {
// select the id of the script that contains your worker code
const blob = new Blob([
document.querySelector('#myWebWorker').textContent
], {type: "text/javascript"})
// Note: window.webkitURL.createObjectURL() in Chrome 10+.
const worker = new Worker(window.URL.createObjectURL(blob));
worker.onMessage = (e) => {
console.log('received data in main thread')
};
}
它更像是“上一行”而不是“内联”,但它允许网络工作者在同一个文件中组合和使用。技巧是使用脚本标签并通过将脚本标签分配给上面代码中的给定类型来转换未评估的 javascript。仍然不是最优雅的解决方案,但在将进程推送到另一个线程时非常方便。
你的createWorker函数已经返回了一个worker,所以你可以替换:
var worker = createWorker(generic);
var getEquipmentW = new Worker(worker);
有了这个:
var getEquipmentW = createWorker(generic);