This article will show you how to use Web Worker, a multi-threading solution.

By using Web Workers, a web application can run a script operation on a background thread independent of the main thread. The benefit of this is that time-consuming processing tasks can be performed in a separate thread, allowing the main thread (usually the UI thread) to not be blocked/slowed down as a result.

Create a worker object using a constructor (for example, Worker()) that accepts a JavaScript file URL—this file contains the code that will be run in the worker thread.

However, once a worker is created, it will continue to run and will not be interrupted by the activities of the main thread. This is conducive to the flexibility of responding to the main thread at any time, but it will also cause a waste of resources, so it should not be overused and be careful to close it after use. . In other words: if the worker has no instance reference, the worker will be closed immediately after becoming idle; if the worker real column reference is not 0, the worker will not be closed when idle.

important point

  1. Same origin restriction:
    The script file executed by the worker thread must have the same origin as the script file of the main thread. This is of course. You cannot allow the worker thread to read files everywhere on other people's computers.
  2. File restrictions
    For security reasons, the worker thread cannot read local files. The script it loads must come from the network and must have the same origin as the script of the main thread.
  3. DOM operations restrict
    the worker thread to run in another global context different from the main thread's window. The DOM object of the web page where the main thread is located cannot be read, and objects such as document and window cannot be obtained, but navigator, location (read-only) can be obtained. ), XMLHttpRequest, setTimeout family and other browser APIs.
  4. Communication restrictions:
    The worker thread and the main thread are not in the same context and cannot communicate directly. They need to communicate through the postMessage method.
  5. The script restricts
    the worker thread from executing alert and confirm, but it can use the XMLHttpRequest object to issue ajax requests.

example

main thread

Worker() constructor, the first parameter is the URL of the script (must comply with the same origin policy), this parameter is required, and only JS scripts can be loaded, otherwise an error will be reported. The second parameter is the configuration object, which is optional. One of its functions is to specify the name of the Worker to distinguish multiple Worker threads.

<div>
    Worker 输出内容:<span id='app'></span>
    <input type='text' title='' id='msg'>
    <button onclick='sendMessage()'>发送</button>
    <button onclick='stopWorker()'>stop!</button>
</div>

<script>
    if (typeof (Worker) === 'undefined') // 使用Worker前检查一下浏览器是否支持
        document.writeln(' Sorry! No Web Worker support.. ')
    else {
        window.w = new Worker('worker.js')
        // 指定worker线程发消息时的回调,也可以通过 worker.addEventListener('message',cb)的方式
        window.w.onmessage = ev => {
            document.getElementById('app').innerHTML = ev.data
        }
        // 指定worker线程发生错误时的回调,也可以 worker.addEventListener('error',cb)
        window.w.onerror = err => {
            w.terminate()
            console.log(err.filename, err.lineno, err.message) // 发生错误的文件名、行号、错误内容
        }

        function sendMessage() {
            const msg = document.getElementById('msg')
            // 主线程往worker线程发消息,消息可以是任意类型数据,包括二进制数据
            window.w.postMessage(msg.value)
        }

        function stopWorker() {
            // 主线程关闭worker线程
            window.w.terminate()
        }
    }
</script>
API in the main thread, worker represents an instance of Worker
  • worker.postMessage: The main thread sends a message to the worker thread. The message can be any type of data, including binary data.
  • worker.terminate: The main thread closes the worker thread
  • worker.onmessage: Specifies the callback when the worker thread sends a message, or through worker.addEventListener('message',cb)
  • worker.onerror: Specify the callback when an error occurs in the worker thread, or worker.addEventListener('error',cb)
worker thread

The global object in the Worker thread is self, which represents the sub-thread itself. At this time, this points to self.

// worker.js
let i = 1

function simpleCount() {
    i++
    self.postMessage(i)
    setTimeout(simpleCount, 1000)
}

simpleCount()

// 指定主线程发worker线程消息时的回调,也可以self.addEventListener('message',cb)
self.onmessage = ev => {
    // worker线程往主线程发消息,消息可以是任意类型数据,包括二进制数据
    self.postMessage(ev.data + ' 呵呵~')
}

// 指定worker线程发生错误时的回调,也可以 self.addEventListener('error',cb)
self.onerror = er =>{
    // worker线程关闭自己
    self.close()
}
API, self in the worker thread represents the child thread itself
  • self.postMessage: The worker thread sends a message to the main thread. The message can be any type of data, including binary data.
  • self.close: worker thread closes itself
  • self.onmessage: Specify the callback when the main thread sends worker thread messages, or self.addEventListener('message',cb)
  • self.onerror: Specify the callback when an error occurs in the worker thread, or self.addEventListener('error',cb)
API for loading scripts in worker threads:
importScripts('script1.js')	// 加载单个脚本
importScripts('script1.js', 'script2.js')	// 加载多个脚本

Actual combat scenario

  1. Some encryption and decryption algorithms for encrypted data
    are relatively complex, or when encrypting or decrypting a lot of data, this will consume a lot of computing resources and cause the UI thread to become unresponsive. Therefore, this is a good time to use Web Worker. Using Worker threads can make users more seamless. Stitched operation UI.
  2. Prefetching data
    Sometimes in order to improve the data loading speed, you can use the Worker thread to obtain the data in advance, because the Worker thread can use XMLHttpRequest.
  3. Pre-rendering
    needs to be calculated in certain rendering scenarios, such as when rendering complex canvases, such as reflection, refraction, light and shadow, materials, etc. The logic of these calculations can be executed using Worker threads, or multiple Worker threads can be used. Here Here is an example of ray tracing.
  4. Complex data processing scenarios:
    Some retrieval, sorting, filtering, and analysis are very time-consuming. In this case, you can use Web Worker to do it without occupying the main thread.
  5. Preload images.
    Sometimes there are many images on a page, or there are several very large images. If lazy loading is not considered due to business restrictions, you can also use Web Worker to load images.

Available features for Web Workers

Due to the multi-threaded nature of Web Workers, it can only use a subset of JavaScript functionality. The following is a list of available functions:

  • navigator object
  • location object (read-only)
  • XMLHttpRequest
  • setTimeout()/clearTimeout() 和 setInterval()/clearInterval()
  • Application Cache
  • Use importScripts to reference external scripts
  • Create other web workers

Limitations of Web Workers

Frustratingly, Web Workers don't have access to some very critical JavaScript functionality:

  • DOM (not thread-safe)
  • window object
  • document object
  • parent object

Guess you like

Origin blog.csdn.net/shanghai597/article/details/130921431