据我所知,web worker需要写在一个单独的JavaScript文件中,并像这样调用:
new Worker('longrunning.js')
我正在使用闭包编译器来合并和缩小我所有的JavaScript源代码,我不希望将我的worker放在单独的文件中进行分发。有什么办法可以做到吗?
new Worker(function() {
//Long-running work here
});
既然一级函数对JavaScript如此重要,为什么标准的后台工作方式必须从web服务器加载整个其他JavaScript文件呢?
将Adria的响应放在一个可复制粘贴的函数中,该函数适用于当前的Chrome和FF,但不适用于IE10 (worker from blob会导致安全错误)。
var newWorker = function (funcObj) {
// Build a worker from an anonymous function body
var blobURL = URL.createObjectURL(new Blob(
['(', funcObj.toString(), ')()'],
{type: 'application/javascript'}
));
var worker = new Worker(blobURL);
// Won't be needing this anymore
URL.revokeObjectURL(blobURL);
return worker;
}
下面是一个工作示例http://jsfiddle.net/ubershmekel/YYzvr/
@Trincot's似乎是目前为止最好的。然而,也许我们可以进一步发展它。所以我的想法是,
我们不要修改Function.prototype。
为线程操作获取函数的承诺/线程化版本。
如果需要,请确保仍然可以同步调用该函数。
因此,我们用spawn方法定义了Threadable类。一旦我们将函数设为该类的成员,那么它就是可线程的:)
class Threadable extends Function {
constructor(f){
super("...as",`return ${f.toString()}.apply(this,as)`);
}
spawn(...as){
var code = `self.onmessage = m => self.postMessage((${this.toString()}).apply(self,m.data));`,
blob = new Blob([code], {type: "text/javascript"}),
wrkr = new Worker(window.URL.createObjectURL(blob));
return new Promise( (v,x) => ( wrkr.onmessage = m => (v(m.data), wrkr.terminate())
, wrkr.onerror = e => (x(e.message), wrkr.terminate())
, wrkr.postMessage(as)
)
);
}
}
function add(...nums) {
return nums.reduce((a,b) => a+b);
}
var addT = new Threadable(add);
addT.spawn(1,2,3,4)
.then(m => console.log(`Promisified thread returned ${m}`));
console.log(`Synchronous invocation of addT returned ${addT(1,2,3,4)}`);
https://developer.mozilla.org/es/docs/Web/Guide/Performance/Using_web_workers
// Syntax: asyncEval(code[, listener])
var asyncEval = (function () {
var aListeners = [], oParser = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D");
oParser.onmessage = function (oEvent) {
if (aListeners[oEvent.data.id]) { aListeners[oEvent.data.id](oEvent.data.evaluated); }
delete aListeners[oEvent.data.id];
};
return function (sCode, fListener) {
aListeners.push(fListener || null);
oParser.postMessage({
"id": aListeners.length - 1,
"code": sCode
});
};
})();