Introduction to JS Worker and its use in Vue
1. Worker introduction
Javascript is single-threaded and will block the execution of the program. Ajax is often used to exchange data with the server. Although it will not block the program, it cannot change the essence of single-threading. In response to this shortcoming, h5 has a new function worker, which supports multi-threading.
The worker can create sub-threads, which will be executed in a new environment without blocking the main thread.
Worker also has a subclass - SharedWorker shared thread, which is often used for communication between different tabs of the browser, see here for details .
2. Worker application scenarios
- Encrypt large amounts of data
- Read and parse large json files
- Highlight code syntax or other live text formatting
- Spell Check
- Analyze video or audio data
- Handling very large arrays
3. Worker use
1. Compatibility
It is not supported below ie10, and there are basically no problems in other cases.
Compatibility judgment:if (!Worker) { throw new Error('当前浏览器不支持多线程') }
2. Create
- js file for creating child threads: ChildThread.js
- create child thread
const childThread = new Worker("ChildThread.js");
3. Communication
- Both the main thread and the child thread
postMessage()
send messages through the method - Receiving a message is done using
onmessage = (e)=>{}
, oraddEventListener('message', (e)=>{})
4. The simplest demo
The simplest demo is used here to illustrate the usage. The following demo main thread sends a message to the sub-thread, and the sub-thread returns a message after receiving it.
4.1 Main thread html page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Worder-简单示例</title>
</head>
<body>
<h1>Worder-简单示例</h1>
<h3>使用调试面板查看</h3>
<script type="text/javascript">
// 兼容性判断
if (!Worker) {
throw new Error('当前浏览器不支持多线程')
}
// 创建子线程
const childThread = new Worker('child/ChildThread.js')
// 向子线程发送数据
childThread.postMessage('How are you?')
// 监听子线程信息
childThread.addEventListener('message', (e) => {
console.log('主线程收到子线程信息: ', e.data)
})
</script>
</body>
</html>
4.2 Sub-thread code
child/ChildThread.js
// 接收主线程信息
self.addEventListener('message', (e) => {
console.log('子线程收到主线程信息:', e.data)
postMessage('I am fine.')
})
4.3 Result output
5. close
When the thread ends, it can be closed manually, otherwise it will remain resident.
The way the main thread closes the sub-thread: worker.terminate()
the internal closing mode of the sub-thread:self.close()
6. Error handling
When an error occurs in the child thread, the main thread can handle it by adding a listener
worker.addEventListener('error', (e)=>{});
7. Import file
In the child thread, you can use importScripts to import external js files, the way is:
importScripts('script1.js', 'script2.js')
8. Multi-thread nesting
In the sub-thread, you can use again new Worder('**.js')
to create your own sub-thread, realize thread nesting, and handle complex business
4. Notes on using Worker
-
The context of the child thread is itself, which can be obtained through self or this;
-
The message passed between the main thread and the sub-thread is copied rather than shared , that is to say, if the passed parameter is an object, the program will use the JSON method to encode/decode the object;
-
The main thread and the sub-thread have different contexts and different scopes. The sub-thread cannot call the dom and methods of the main thread. Specifically, it
cannot be used :- window object
- document object
- parent object
- alert()
- confirm()
You can use :
- navigator object
- location object (read-only)
- XMLHttpRequest
- setTimeout()/clearTimeout() 和 setInterval()/clearInterval()
- application cache
- Import external scripts using the importScripts() method
- Spawn additional Web Workers
Five, use Worker in vue
1. Regular use
1.1 Create sub-thread js
Create a child thread js: 根目录/public/worker/ChildThread.js
, the code is as follows:
// 接收主线程信息
self.addEventListener('message', (e) => {
console.log('Worker子线程收到主线程信息:', e.data)
postMessage('I am fine.')
})
1.2 Use of vue files
Create a vue file, the code is as follows
<template>
<div><h1>worker使用</h1></div>
</template>
<script>
export default {
created() {
// 兼容性判断
if (!window.Worker) {
throw new Error('当前浏览器不支持多线程')
}
// 创建子线程
this.childThread = new Worker('/worker/ChildThread.js')
// 向子线程发送数据
this.childThread.postMessage('How are you?')
// 监听子线程信息
this.childThread.addEventListener('message', this.messageHandle)
},
methods: {
// 消息处理
messageHandle(e) {
console.log('Worker主线程收到子线程信息: ', e.data)
},
},
destroyed() {
// 记得销毁线程
this.childThread.removeEventListener('message', this.messageHandle)
this.childThread.terminate()
},
}
</script>
2. Use of vue-worker
In vue, workers can be used through the vue-worker library, and the syntax is different.
2.1vue-worker installation
npm i -S vue-worker
2.2 Registration
Introduced in main.js
import Vue from 'vue'
import VueWorker from 'vue-worker'
import App from 'App.vue'
Vue.use(VueWorker)
new Vue({
el: '#app',
render: h => h(App)
})
2.3 use
- Create a thread worker in create and define callback methods for different messages;
- Send messages to sub-threads through the postMessage method
(第二个参数必须是数组)
, define then to handle callbacks, and define catch to handle exceptions
<template>
<div><h1>vue-worker使用</h1></div>
</template>
<script>
export default {
created() {
// 创建子线程
this.worker = this.$worker.create([
{
message: 'to child',
func: (data) => {
console.log('子线程收到主线程信息:', data)
return 'i am fine'
},
},
])
// 主线程发生消息
this.worker
// postMessage第二个参数必须是数组
.postMessage('to child', ['how are you'])
.then((res) => {
console.log('主线程收到子线程信息:', res)
})
.catch((e) => {
console.error(e)
})
},
destroyed() {
// 记得销毁线程
this.worker = null
},
}
</script>
The above example is the simplest demo used by vue-worker
兄弟,都看到这里了,点个赞再走呗