This time I will bring you a detailed explanation of the use of H5 multi-threading (Worker SharedWorker), what are the precautions when using H5 multi-threading (Worker SharedWorker), the following is a practical case, let's take a look.
There is no doubt that JavaScript does not have multi-threading. It can only do one thing one thing, and then do the next thing after finishing one thing. If your js takes a long time to do one thing, the browser will freeze for a while and not respond to the user's operations. What can you do? Thank God, HTML5 provides us with a mechanism to implement multi-threading. You must have used such a good thing before, but it doesn’t matter, let’s review it together!
1. Worker class
1. Method introduction
(1) Constructor new Worker(arg): The parameter indicates the js file where the code to be executed by your thread is located, such as 'myworker.js'. The constructor of course returns an instance of the Worker class
(2 ) worker.postMessage(message): This method means sending a message from the main thread to the sub-thread or the sub-thread sending a message to the main thread. The message is generally a string , or it can be Convert a js object into a string and send it
(3) There is also a message event on the worker. When someone sends a message to this worker instance, the event is triggered. We can get the data from his event object. Obtain the posted value in the attribute
You can see that the API of the Woker class is quite simple, with only two most commonly used methods and one event. Let's take a look at it through a practical example.
//main.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>main</title> </head> <body> <p id="out"></p> <input type="text" name="" id="txt"> <button id="btn">发送</button> <script type="text/javascript"> var out = document.getElementById("out"); var btn = document.getElementById("btn"); var txt = document.getElementById("txt"); var worker = new Worker("thread1.js"); btn.addEventListener("click",function(){ var postData = txt.value; worker.postMessage(postData); },false); worker.addEventListener('message',function(e){ out.innerText = e.data; },false); </script> </body> </html> //thread1.js onmessage = function(event){ var res = event.data+"帅气!"; postMessage(res); }
When I enter "Big~Bear" in the text box and click the send button, the following effect will appear
Simple analysis, I am in the main thread by thead1.js creates an instance of Worker. When the button is clicked, its postMessage method is called to send the content in the text box to thread1.js. How does our thread1.js do it? That's it, it listens to the message event, and the main thread triggers the event when it sends a message, and executes the callback function. The callback function gets the value sent from the event object, and then adds "handsome!" to this value. , and then send it back. The main thread also listens to the worker's message event, so it will be triggered when a message passes, and the message content will be displayed in p, so you can see the above effect.
Perhaps you will use this for what purpose? There is really no use here. Here we can always complete the operation of adding "handsome!" in the main thread, because its complexity is O(1) (haha, I am learning algorithms recently!), but if it is not such a simple operation Woolen cloth? The advantage of this method is that no matter how complicated the work your sub-thread does, it will not stop the main thread. The main thread will continue to do whatever it is doing. Once the sub-thread has processed the data, it can just take it over. .
Teacher Lu will be able to create a new sub-thread by calling new Worker() in the sub-thread. I found that this is not possible and an undefined error will be reported, which means that the Worker construct cannot be called in the sub-thread. Function, I thought I was wrong at first, but later I checked the official documentation and found that there was no relevant description.
Let’s look at an example of calling multiple sub-threads in the main thread:
//main.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>main</title> </head> <body> <p id="out"></p> <input type="text" name="" id="txt"> <button id="btn">发送</button> <script type="text/javascript"> var out = document.getElementById("out"); var btn = document.getElementById("btn"); var txt = document.getElementById("txt"); var worker1 = new Worker("thread1.js"); var worker2 = new Worker("thread2.js"); btn.addEventListener("click",function(){ var postData = txt.value; worker1.postMessage(postData); },false); worker1.addEventListener('message',function(e){ worker2.postMessage(e.data); },false); worker2.addEventListener('message',function(e){ out.innerText = e.data; },false); </script> </body> </html> //thread1.js onmessage = function(event){ var res = event.data+"帅气!"; postMessage(res); } //thread2.js onmessage = function(event){ var res = event.data+"没骗你哟!"; postMessage(res); close(); }
The main thread needs two threads to complete a task. It creates two threads worker1 and 2, and first calls worker1 Request, after getting the returned data, request worker2 again, and at the same time hand over the data processed by worker1 to worder2 for processing, and then get the final result and display it on the page.
In the child thread, you can introduce other js files and then call them, such as the example below.
//main.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>main</title> </head> <body> <p id="out"></p> <input type="text" name="" id="txt"> <button id="btn">发送</button> <script type="text/javascript"> var out = document.getElementById("out"); var btn = document.getElementById("btn"); var txt = document.getElementById("txt"); var worker1 = new Worker("thread1.js"); btn.addEventListener("click",function(){ var postData = txt.value; worker1.postMessage(postData); },false); worker1.addEventListener('message',function(e){ out.innerText = e.data; },false); </script> </body> </html> //thread1.js importScripts('tools.js') onmessage = function(event){ var res = handler(event.data); postMessage(res); } //tools.js function handler(data){ return data+"加油加油!" }
You can see that our thread1.js does not have a file called tools.js, but it imports a js file through importScripts(), and then you can call the exposed methods inside.
2. SharedWorker class
The essence of SharedWorker is share. Different threads can share one thread, and their data is also shared.
Let’s discuss it directly with examples.
使用方法一:
//main.html <!DOCTYPE HTML> <head> <title>Shared workers: demo 1</title> </head> <body> <p id="log"></p> <script> var worker = new SharedWorker('shared.js'); var log = document.getElementById('log'); worker.port.onmessage = function(e) { // note: not worker.onmessage! log.textContent += '\n' + e.data; } </script> </body> </html> //shared.js onconnect = function(e) { var port = e.ports[0]; port.postMessage('Hello World!'); }
这是从w3c拿得一个例子,下面先看第二种方法,再做分析
<!DOCTYPE HTML> <html> <head> <title>Shared workers: demo 2</title> </head> <body> <p id="log"></p> <script> var worker = new SharedWorker('shared.js'); var log = document.getElementById('log'); worker.port.addEventListener('message', function(e) { log.textContent += '\n' + e.data; }, false); worker.port.start(); // note: need this when using addEventListener worker.port.postMessage('ping'); </script> </body> </html> //shared onconnect = function(e) { var port = e.ports[0]; port.postMessage('Hello World!'); port.onmessage = function(e) { port.postMessage('pong'); // not e.ports[0].postMessage! // e.target.postMessage('pong'); would work also } }
第一种方法中是使用事件句柄的方式将听message事件,不需要调用worker.port.start(),第二种方法是通过addEventListener()方法监听message事件,需要worker.port.start()方法激活端口。他们不同于worker,当有人和他通信时触发connect事件,然后他的message事件是绑定在messagePort对象上的,不想worker那样,你可以回头看看worker是怎么做的。
那么sharedWorker是怎么共享数据的呢?请看下面的例子。
//main1 和main2都是这样 <!DOCTYPE HTML> <html> <head> <title>Shared workers: demo 2</title> </head> <body> <p id="log"></p> <input type="text" name="" id="txt"> <button id="get">get</button> <button id="set">set</button> <script> var worker = new SharedWorker('shared.js'); var get = document.getElementById('get'); var set = document.getElementById('set'); var txt = document.getElementById('txt'); var log = document.getElementById('log'); worker.port.addEventListener('message', function(e) { log.innerText = e.data; }, false); worker.port.start(); // note: need this when using addEventListener set.addEventListener('click',function(e){ worker.port.postMessage(txt.value); },false); get.addEventListener('click',function(e){ worker.port.postMessage('get'); },false); </script> </body> </html> //shared var data; onconnect = function(e) { var port = e.ports[0]; port.onmessage = function(e) { if(e.data=='get'){ port.postMessage(data); }else{ data=e.data; } } }
这里分析一波,我们在main1.html的文本框输入数据,点击set,然后在main2.html中点击get法现能够获取到我们在main1.html中设置的数据,这说明我们的sharedWorker事实上是单例的,就像java中的static类一样,不管new多少个,实际上只有一个,这样我们的不同线程就可以共享到sharedWorker中的数据了。这里把图给上,记得有篇文章没给图,然后有人给我建议了,问能不能给图。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
The above is the detailed content of Detailed explanation of the use of H5 multi-threading (Worker SharedWorker). For more information, please follow other related articles on the PHP Chinese website!