据我所知,web worker需要写在一个单独的JavaScript文件中,并像这样调用:

new Worker('longrunning.js')

我正在使用闭包编译器来合并和缩小我所有的JavaScript源代码,我不希望将我的worker放在单独的文件中进行分发。有什么办法可以做到吗?

new Worker(function() {
    //Long-running work here
});

既然一级函数对JavaScript如此重要,为什么标准的后台工作方式必须从web服务器加载整个其他JavaScript文件呢?


当前回答

使用我的小插件https://github.com/zevero/worker-create

var worker_url = Worker.createURL(function(e){
  self.postMessage('Example post from Worker'); //your code here
});
var worker = new Worker(worker_url);

其他回答

看一下vkThread插件。使用htis插件,你可以在主代码中获取任何函数,并在线程(web worker)中执行它。所以,你不需要创建一个特殊的“web-worker文件”。

http://www.eslinstructor.net/vkthread/

——瓦迪姆

你可以在同一个javascript文件中使用内联的webworker。

下面的文章将帮助您轻松理解webworker及其局限性和调试webworker。

精通网络工作者

近期答案(2018)

你可以使用Greenlet:

移动一个异步函数到它自己的线程中。Workerize的简化单功能版本。

例子:

import greenlet from 'greenlet'

const getName = greenlet(async username => {
  const url = `https://api.github.com/users/${username}`
  const res = await fetch(url)
  const profile = await res.json()
  return profile.name
})

console.log(await getName('developit'))

一个简单的承诺版本,Function#callAsWorker,它接受一个thisArg和参数(就像call一样),并返回一个承诺:

Function.prototype.callAsWorker = function (...args) { return new Promise( (resolve, reject) => { const code = `self.onmessage = e => self.postMessage((${this.toString()}).call(...e.data));`, blob = new Blob([code], { type: "text/javascript" }), worker = new Worker(window.URL.createObjectURL(blob)); worker.onmessage = e => (resolve(e.data), worker.terminate()); worker.onerror = e => (reject(e.message), worker.terminate()); worker.postMessage(args); }); } // Demo function add(...nums) { return nums.reduce( (a,b) => a+b ); } // Let the worker execute the above function, with the specified arguments add.callAsWorker(null, 1, 2, 3).then(function (result) { console.log('result: ', result); });

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
    });
  };

})();