Web workers without a separate Javascript file?

2019-01-02 16:38发布

As far as I can tell, web workers need to be written in a separate JavaScript file, and called like this:

new Worker('longrunning.js')

I'm using the closure compiler to combine and minify all my JavaScript source code, and I'd rather not have to have my workers in separate files for distribution. Is there some way to do this?

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

Given that first-class functions are so crucial to JavaScript, why does the standard way to do background work have to load a whole 'nother JavaScript file from the server?

23条回答
萌妹纸的霸气范
2楼-- · 2019-01-02 16:49

You can use web workers in same javascript fie using inline webworkers.

The below article will address you to easily understand the webworkers and their limitations and debugging of webworkers.

Mastering in webworkers

查看更多
梦该遗忘
3楼-- · 2019-01-02 16:52

here console:

var worker=new Worker(window.URL.createObjectURL(new Blob([function(){
  //Long-running work here
  postMessage('done');
}.toString().split('\n').slice(1,-1).join('\n')],{type:'text/javascript'})));

worker.addEventListener('message',function(event){
  console.log(event.data);
});
查看更多
十年一品温如言
4楼-- · 2019-01-02 16:52

I discovered that CodePen currently does not syntax-highlight inline <script> tags that are not type="text/javascript" (or which have no type attribute).

So I devised a similar but slightly different solution using labeled blocks with break, which is the only way you can bail from a <script> tag without creating a wrapper function (which is unnecessary).

<!DOCTYPE html>
<script id="worker1">
  worker: { // Labeled block wrapper

    if (typeof window === 'object') break worker; // Bail if we're not a Worker

    self.onmessage = function(e) {
      self.postMessage('msg from worker');
    };
    // Rest of your worker code goes here.
  }
</script>
<script>
  var blob = new Blob([
    document.querySelector('#worker1').textContent
  ], { type: "text/javascript" })

  // Note: window.webkitURL.createObjectURL() in Chrome 10+.
  var worker = new Worker(window.URL.createObjectURL(blob));
  worker.onmessage = function(e) {
    console.log("Received: " + e.data);
  }
  worker.postMessage("hello"); // Start the worker.
</script>

查看更多
旧时光的记忆
5楼-- · 2019-01-02 16:53

Depending on your use case you can use something like

task.js Simplified interface for getting CPU intensive code to run on all cores (node.js, and web)

A example would be

function blocking (exampleArgument) {
    // block thread
}

// turn blocking pure function into a worker task
const blockingAsync = task.wrap(blocking);

// run task on a autoscaling worker pool
blockingAsync('exampleArgumentValue').then(result => {
    // do something with result
});
查看更多
宁负流年不负卿
6楼-- · 2019-01-02 16:54

http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers

What if you want to create your worker script on the fly, or create a self-contained page without having to create separate worker files? With Blob(), you can "inline" your worker in the same HTML file as your main logic by creating a URL handle to the worker code as a string


Full example of BLOB inline worker:

<!DOCTYPE html>
<script id="worker1" type="javascript/worker">
  // This script won't be parsed by JS engines because its type is javascript/worker.
  self.onmessage = function(e) {
    self.postMessage('msg from worker');
  };
  // Rest of your worker code goes here.
</script>
<script>
  var blob = new Blob([
    document.querySelector('#worker1').textContent
  ], { type: "text/javascript" })

  // Note: window.webkitURL.createObjectURL() in Chrome 10+.
  var worker = new Worker(window.URL.createObjectURL(blob));
  worker.onmessage = function(e) {
    console.log("Received: " + e.data);
  }
  worker.postMessage("hello"); // Start the worker.
</script>

查看更多
只靠听说
7楼-- · 2019-01-02 16:54

Try to use jThread. https://github.com/cheprasov/jThread

// You can use simple calling like this
jThread(
    function(arr){
        //... some code for Worker
        return arr;
    }
    ,function(arr){
        //... done code
    }
)( [1,2,3,4,5,6,7] ); // some params
查看更多
登录 后发表回答