Home  >  Article  >  Web Front-end  >  HTML5 multi-threaded JavaScript solution Web Worker-detailed code introduction of dedicated Worker and shared Worker

HTML5 multi-threaded JavaScript solution Web Worker-detailed code introduction of dedicated Worker and shared Worker

黄舟
黄舟Original
2017-03-11 16:18:182122browse

It has to be said that HTML5 does provide a lot of powerful features
It even subverts our previous understanding of JavaScript single thread
It provides a JavaScript multi-threaded solution
This new feature is called Web Worker
(There was no multi-threading before, setTimeout and so on were still single-threaded in nature)
Although it is multi-threaded programming
But we don’t have to worry about the multi-threading problems encountered by traditional multi-threaded languages ​​​​C++, Java, etc.
Let’s take a look at what is Web Worker

Dedicated Worker

Dedicated Worker (Dedicated Worker) is the most commonly used Web Worker
And each browser implements it well

Declaration

When do we need multi-threading?
For example, we need complex calculations,

//demo.jsfunction calculate(){
  var ret = 0;  for(var i = 1; i <= 1e9; i++){
    ret += i;
  }  return ret;
}var result;var start;var end;
start = +new Date();
result = calculate();
end = +new Date();
console.log(result); //500000000067109000console.log(end - start); //977

We calculated Adding the value from 1 to 1 billion
stops the rendering of the page for nearly 1 second
It is quite unfriendly to the user experience
Although there will not be such crazy calculations in development
But we may encounter intensive and complex tasks
At this time we may want to open a new independent thread to complete
And we only need to pay attention to the result value


HTML5 allows We use Worker thread
Its work content needs to be written in a separate js file
Let our multiple program blocks run concurrently

var worker = new Worker(&#39;scripts/worker.js&#39;);

In this way to instantiate a worker
The parameter is the path to the js file (the HTML main file and Worker file need to meet the same origin policy)
When the program runs here
This file will be loaded into a Worker
The browser will start An independent thread runs the js file

Interaction

Our main thread and worker thread interact based on the event mechanism
In other words,
They all need to subscribe Events to communicate with each other (onmessage event)

//主线程
worker.addEventListener(&#39;message&#39;, function(e){
    //e.data为从worker线程得到的数据
});
worker.possMessage(...);//向worker线程发送数据
//工作线程
addEventListener(&#39;message&#39;, function(e){
    //e.data为从主线程得到的数据
});
possMessage(...);//向主线程发送数据

Their data binding is similar to that of data sending
It’s just that there is no need to call the API with an object in the worker file
This is the complex calculation we just did You can let the worker do it

//worker.jsfunction calculate(){
  var ret = 0;  for(var i = 1; i <= 1e9; i++){
    ret += i;
  }  return ret;
}
postMessage(calculate());
//demo.jsvar worker = new Worker(&#39;scripts/worker.js&#39;);
worker.addEventListener('message', function(e){
  console.log(e.data); //500000000067109000}, false);

In the HTML5 Web Worker specification
worker can also instantiate its own worker (it feels unnecessary)
called subworker (thread nested thread )
But I tested it, chrome does not support subworker yet
But it is said that Firefox supports

termination

Since we can create workers
, then we should also be able to terminate it worker lets it stop working
It can be terminated in both the main thread and the worker thread
You only need to call the API in the worker object or the scope of the worker
One is that we let it end the work
The other is it Strike by yourself

//主线程worker.terminate();
//工作线程close();

But I think we usually
will terminate it by calling the terminate method on the worker object
This will be safer

Environment

I said it at the beginning
We don’t have to worry about the multi-threading problems encountered by traditional multi-threaded languages
For example, to prevent them from seizing resources...
Incredibly complex locking mechanism
why?
Because inside the worker
we cannot access any resources of the main program at all
It is a completely independent thread
Web Worker has the following restrictions:

  • Same origin policy restriction

  • Cannot access page DOM and other resources

  • Browser implementation is different

But we can do these things inside the worker:

  • Can perform network operations (Ajax, Web Sockets)

  • Can use timing Device (set/clearTimeout(), set/clearInterval())

  • Access copies of some important global variables and functions (navigator, location, JSON, applicationCache)

  • You can use importScrips() to load additional js scripts

importScripts(&#39;foo.js&#39;,&#39;bar.js&#39;);importScripts(&#39;foobar.js&#39;);

If you are curious, you can use it in the workerconsole.log(this);
Check what is in its scope

Application

About its application
We will use Web Worker to do these things

  • Complex mathematical calculation

  • Complex data sorting

  • Data processing (compression, image processing...)

  • High-traffic network communication

Shared Worker

In addition to the dedicated thread, there is also a shared thread Shared Worker
You can find out
I just checked Take a look
So far, only Google, Firefox and OPEN have implemented this technology


If our website or App can load multiple tabs at the same time (Tab page)
Then if we use ordinary workers, we may repeatedly create multiple threads
This will inevitably occupy system resources
At this time, if we can allow the page instances of the App or the entire site to share a worker
That would be great~
The usage of shared threads and dedicated threads are similar, just a little more complicated

var worker = new SharedWorker(&#39;scripts/worker.js&#39;);

由于共享线程需要与多个程序实例或页面链接
所以它需要通过某种方式来了解消息的来源
这个方式就是利用一个唯一标识符port(端口)
这样我们刚才的例子就需要写成这个样子

//demo.jsvar worker = new SharedWorker(&#39;scripts/worker.js&#39;);
worker.port.addEventListener('message', function(e){
  console.log(e.data); //500000000067109000}, false);
worker.port.start();

在主线程中
端口连接必须初始化
使用API worker.port.start();

//worker.jsfunction calculate(){
  var ret = 0;  for(var i = 1; i <= 1e9; i++){
    ret += i;
  }  return ret;
}
addEventListener(&#39;connect&#39;, function(e){
  var port = e.ports[0];
  port.start();
  port.postMessage(calculate());
});

在共享worker内部同样需要初始化端口连接port.start();
除此之外,我们还需要处理额外事件onconnect
这个事件为我们的特定连接提供了端口对象
var port = e.ports[0];用于获取连接分配的端口


我们的onmessage事件就可以写在onconnect事件处理函数内部

addEventListener(&#39;connect&#39;, function(e){
  var port = e.ports[0];
  port.addEventListener(&#39;message&#39;, function(e){    ...
    port.postMessage(...);    ...
  });
  port.start();
});

除此之外,其他的功能共享Worker和专用Worker都是一样的

The above is the detailed content of HTML5 multi-threaded JavaScript solution Web Worker-detailed code introduction of dedicated Worker and shared Worker. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn