1-Web Worker Actual operation steps

Dedicated Worker

Let’s start with an example of using the Web Worker to calculate the Fibonacci sequence. The project address

First, we need to create the Worker instance through the Worker() constructor, which takes only one parameter, which is the address of the thread script, which must comply with the same-origin policy.

I created a worker object using the dedicate-worker.js file in the same directory. When the initialization was complete, the browser background thread would run the script again.

var worker = new Worker('dedicate-worker.js');
Copy the code

How does the main thread (page) communicate with the background thread Worker? This is where the postMessage method comes in.

worker.postMessage(message, [transfer]);
Copy the code

The postMessage method takes two parameters, the first is the data information passed between workers, and the second is an array used to transfer object ownership.


      
*/
/ / js parts function normalPost(num) { worker.postMessage(num); } Copy the code

In the code above, when we click the corresponding button, we send a number to the corresponding child thread. The backend child needs to listen for the onMessage event in order to receive data from the main process. This event accepts a MessageEvent object, where the data property is the data passed in by the main process.

// dedicate-worker.js
// Fibonacci sequence
function fabonacci(n) {
    if (n === 0) {
        return 0;
    }
    if (n === 1) {
        return 1;
    }
    return fabonacci(n - 1) + fabonacci(n - 2);
}

onmessage = function(messageEvent) {
    var str = messageEvent.data;
    str = typeof str === 'number' ? String(str) : str;
    switch (str) {
	    / /...
        case (str.match(/ [0-9]) || {}).input:
            var result = fabonacci(Number(str));
            postMessage({msg: str+The Fibonacci sequence of 'is:' + result, code: 'fobo'});
            break;
        default:
            postMessage({msg: 'Hi, bro. Take your time.'.code: ' '});
            break; }}Copy the code

In the above code, we use onMessage to listen for the data transmitted by the main thread. If the corresponding data operation is completed, we directly call the postMessage method to transmit the corresponding result. Note that in the script of the child process, The reason the global scope has changed is that postMessage methods can be called directly, but this is not possible in the main process. Instead, the corresponding Wroker object needs to be called.

Back to the main process code, here we also need to let the corresponding worker listen to the onMessage event to accept the data passed by the child thread.

worker.addEventListener('message', (e) => {
    var res = e.data;
    switch (e.data.code) {
        default:
            app.textContent = res.msg;
            break;
    }
    // ...
});
Copy the code

Because workers are still resource-intensive, they can be shut down when they are not useful by calling terminate.

var worker = new Worker('dedicate-worker.js');
worker.terminate();
Copy the code

shared Worker

We implement a multi-tab sharing partial data effect. Something like this:

The SharedWorker creation method is similar to that of a dedicated Worker, which calls the SharedWorker constructor. The syntax is as follows:

new SharedWorker(aURL, name);
Copy the code

AURL indicates the address of the script, and name indicates the name of the child thread. Threads with the same name can be shared, but they still follow the same origin policy. In our project, we created this:

var shareWorker = new SharedWorker('share-worker.js'.'sharedWork');
Copy the code

Similarly, we can pass information to the child process through the postMessage method, but because the SharedWorker implementation is different, we need to call postMessage through the port property of the instance.

input.addEventListener('change', (e) => {
    shareWorker.port.postMessage({value: e.target.value, type: 'write'});
})
Copy the code

In the code above, we trigger the main thread to pass information to the child thread by listening for the change event in the input box. The subthread connects to the main thread in a slightly different way due to different scopes. We connect to the main thread by listening onConnect, and then obtain the MessagePort object by receiving the ports attribute of the parameter. At this point, you can use onMessage and postMessage to process and pass data.

// ...
onconnect = function (messageEvent) { 
    messageEvent.source.addEventListener('message', (event) => {
            swicthByTypeCode(event.data);
    })
    source.start();
}
// ...
Copy the code

In this code, the child thread connects to the main thread, and the MessagePort object listens for message events. Note that if you use addEvevntListener, you need to start it by itself.

debugging

Dedicated Worker ://inspect/#workers

Once you see the most familiar interface, you can debug the debugger. The above only describes simple usage and does not cover some advanced usage such as importScripts application, error handling mechanism, etc. The scope of Worker is different from the scope of window.