An overview of the

Javascript is a single-threaded model where all tasks are done on a single thread and only one task can be processed at a time to prevent DOM clutter.

The function of webworker is to create multiple threads for JS. It allows Woker threads (called child threads) to be created in the main thread. While the main thread is running, the Worker thread also runs in the background (a new JS environment, WorkerGlobalScope). After the Worker completes the calculation, it returns the calculation result to the main thread. Some computationally complex, high-latency tasks are handled by the Worker thread, and the main thread (usually the UI thread) can flow smoothly without blocking.

At present, all browsers except IE support Web workers.

Different from EventLoop

EventLoop

Browser threads include UI threads (rendering pages), JS engine threads (processing JS), GUI event threads (user interactions), HTTP transport threads (XHR requests), timed trigger threads (timers), and so on. The multiple threads of the browser described above are not true multithreading, but actually have JS threads to process the program.

  • The UI thread is mutually exclusive with the JS engine thread, and JS blocks page loading
  • The JS engine thread is asynchronous to the GUI thread
  • The JS engine thread is asynchronous with the HTTP transport thread
  • The JS engine thread is asynchronous with the timer thread

A synchronization task is an immediate task that is executed directly in the main thread. Asynchronous tasks (XHR requests, setTimeout, and so on) are coordinated through EventQueue. When the main thread is empty, it reads the tasks in the Event Queue and pushes them into the cooking thread, which repeats the EventLoop.

WebWorker

Webworkers are multithreading in the true sense of the word, creating child threads that receive control from the main thread.

Application scenarios of Webworker

Computationally intensive code

  1. The js single thread will block.
  2. Timer events are incorrect.

Putting this part of the calculation code on the worker thread does not cause the main thread to scratch.

The use of webworker

Basic usage

The main thread

  1. Create worker thread
/** * new Worker(jsURL[, options]) * @param jsURL indicates the script URL that the Worker will execute * @param options (optional) * @options type: 'classic', // The optional value is classic or module, default classic * @options credentials: 'omit, * @ options set name is the name of the worker DedicatedWorkerGlobalScope global object name attribute. */ const myWorker = new Worker('worker.js')}Copy the code
  1. The main thread sends a message to the worker thread
myWorker.postMessage('hello myWorker');
myWorker.postMessage({ method: 'print', message: 'hello myWorker' });
Copy the code
  1. The main thread receives messages from the worker thread
myWorker.onmessage = function(e) {
    console.log('Message received from worker is ', e.data);
}
Copy the code
  1. Error handling
myWorker.onerror(function (event) {
  console.log([
    'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
  ].join(''));
});
Copy the code
  1. Closing the worker thread
myWorker.terminate();
Copy the code

Worker thread

  1. The worker thread receives the message
onmessage = function(e) {
    console.log('Worker: Message received from main script', e.data.message);
}
Copy the code
  1. The worker thread sends a message to the main thread
onmessage = function(e) {
    console.log('Message received from main script', e.data.message);
    console.log('Posting message back to main script');
    postMessage('Message from worker');
}
Copy the code
  1. Worker loading script
importScripts('subWorker.js');
Copy the code
  1. Closing the worker thread
self.close();
Copy the code

The same page as the Webworker

The above case is to import external JS file, can also load the same file as the main thread code.

  1. ToString () converts JS functions to strings
  2. New Blob(stringFun) specialises the worker script code into binary objects.
  3. Generate a URL from a binary object.
  4. New Worker(URL) Creates the Worker thread.
// index.js
const workerBlock = function(e) {
    console.log('Message received from main script', e.data.message);
    console.log('Posting message back to main script');
    postMessage('Message from worker');
}

const blob = new Blob([`onmessage=${workerBlock.toString()}`], { "type": "text/javascript" });
const url = window.URL.createObjectURL(blob);
const myWorker = new Worker(url);

myWorker.postMessage('hello myWorker');
myWorker.postMessage({ method: 'print', message: 'hello myWorker' });

myWorker.onmessage = function(e) {
    console.log('Message received from worker is ', e.data);
}
Copy the code

worker API

The main thread

  1. Onerror specifies the error event listener function.
  2. Onmessage specifies the message event listener function, through which the sent data can pass$event.dataAccess.
  3. Onmessageerror Specifies a listener function for messageError events. This event is triggered when sent data cannot be serialized into a string.
  4. PostMessage sends a message to the worker thread.
  5. Terminate Terminates the worker thread immediately.

Worker thread

  1. Name (attribute, read only) The name of the worker, specified by new worker.
  2. Onmessage specifies the listener function for message events.
  3. Onmessageerror Specifies a listener function for messageError events.
  4. Close Closes the worker thread.
  5. PostMessage sends a message to the main program that creates the worker thread.
  6. ImportScripts Loads the JS script.

Worker’s global object, WorkerGlobalScope

WorkerGlobalScope is the global object of worker, which contains the properties of JS global object, such as JSON, some properties of Window, XMLHttpRequest, etc.

Webworker considerations

  1. Scripts must come from the network and be the same source as the main thread scripts. Local file systems cannot be loaded (file://)
  2. Unable to access DOM; Cannot access objects such as document, window, parent, etc. You can access navigator, Location (read only), XMLHttpRequest, setTimeout, and other browser apis.
  3. The alert() and confirm() methods cannot be executed.
  4. The main thread and the worker thread are not in the same context, so they cannot communicate directly and must be completed through messages.

Use Webworker under Webpack

  1. Install the worker – loader
npm i -D worker-loader
Copy the code
  1. Parsing worker files
module.exports = {
    chainWebpack: config => {
        // GraphQL Loader
        config.module
            .rule('worker-loader')
            .test(/\.worker\.js$/)
            .use('worker-loader')
            .loader('worker-loader')
            .end()
    }
}
Copy the code
  1. The use of the worker. Js
import Worker from './file.worker.js';

const worker = new Worker()
Copy the code

Reference documentation

Web Worker Tutorial