找回密码
 立即注册
首页 业界区 业界 js中worker的详细讲解

js中worker的详细讲解

秦晓曼 4 天前
什么是 JavaScript Worker?

Worker 是在Web应用程序中实现多线程的机制。
它可以在一个单独的线程中运行脚本,独立于主线程。
这样,我们可以将一些耗时的计算任务交给Worker线程处理。
以保证主线程的不会被阻塞。
为什么需要Worker?

由于JavaScript是单线程的,所有任务在一个线程上执行。
如果遇到一个耗时的任务(比如大规模数据计算、图像处理、复杂算法)。
它会阻塞主线程导致页面无法响应,用户体验变差。
Worker的出现就是为了解决这个问题,将耗时的计算任务放到后台线程去执行。
vue2中如何使用 worker

在vue/cli脚手架中,我们无法直接使用worker。
因为:
1,无法将 Worker 脚本打包为独立的可加载文件。
2,打包后会导致依赖丢失或路径错误。
  1. npm install worker-loader -D
  2. 或者
  3. yarn add worker-loader -D
复制代码
vue.config.js 配置如下
  1. module.exports = {
  2.   chainWebpack:config=>{
  3.     // 下面是worker的配置
  4.     .rule('worker')
  5.     .test(/\.worker\.js$/)
  6.     .use('worker-loader')
  7.     .loader('worker-loader')
  8.     .end();
  9.     // 解决:worker 热更新问题
  10.     config.module.rule('js').exclude.add(/\.worker\.js$/);
  11.   },
  12.   parallel: false,
  13.   chainWebpack: config => {
  14.     // 解决:“window is undefined”报错,这个是因为worker线程中不存在window对象,因此不能直接使用,要用this代替
  15.     config.output.globalObject('this')
  16.   }
  17. }
复制代码
postMessage 子线程给主线发送消息

self.postMessage子线程向主线程发送消息。
在 Web Worker 中,self 指向当前创建的这个 worker 线程,self 是一个全局对象。
self.postMessage()将数据从 worker 线程发送到创建它的主线程。
主线程通知子线程(worker)开始工作
  1. // 创建 worker
  2. this.webWorker = new Worker('./web.worker.js')
  3. // 通知 Worker 子线程可以进行响应的工作。
  4. // 主线程调用worker.postMessage()方法,向 Worker 发消息
  5. this.webWorker.postMessage({ action: 'startFetch' });
复制代码
worker 中来发送网络请求哈

src\views\element.vue 文件
  1. <template>
  2.   
  3.     <h1>使用worker来发发送网络请求</h1>
  4.     <el-button @click="sendFetchHandler">开始发送网络请求</el-button>
  5.     <ul>
  6.       <li v-for="(item,index) in apiBackData" :key="index">{{ item.title }}</li>
  7.     </ul>
  8.   
  9. </template>
复制代码
  1. // 引入网络请求中的方法
  2. import {getList} from '@/request/api.js'
  3. self.onmessage = function(e) {
  4.   console.log("worker:", e)
  5.   if(e.data && e.data.action==='startFetch'){
  6.     //  e.data是主线程发送过来的数据
  7.     getList().then(res=>{
  8.       console.log(1111,res)
  9.       // 假设 是一个数组就是请求成功
  10.       if(Array.isArray(res)){
  11.         //将数据从 worker 线程发送到创建它的主线程
  12.         self.postMessage({
  13.           type: 'fetchSuccess',
  14.           data:{
  15.             data:res,
  16.             message: '获取成功'
  17.           }
  18.         });
  19.       }else{
  20.         // 将数据从 worker 线程发送到创建它的主线程
  21.         self.postMessage({ type: 'fetchError', error: '请求失败' });
  22.       }
  23.     })
  24.   }
  25. };
复制代码
1.png

worker导出表格案例
  1. <template>
  2.   
  3.     <input type="text">
  4.     <br/>
  5.     <el-button @click="exportExcelHandler">导出excel</el-button>
  6.   
  7. </template>
复制代码
2.png

现在我们使用worker来解决添加数据耗时的问题

下载xlsx模块。
  1. npm install --save xlsx
复制代码
使用worker的文件(下载的主页面)
  1. <template>
  2.   
  3.     <input type="text">
  4.     <br/>
  5.     <el-button @click="exportExcelHandler">导出excel</el-button>
  6.   
  7. </template>
复制代码
worker文件(src\views\web.worker.js )
  1. // 引入 xlsx
  2. import {utils} from 'xlsx'
  3. self.onmessage = function(e) {
  4.   console.log("worker:", e)
  5.   if(e.data && e.data.action==='startCreateExcelData'){
  6.     //  e.data是主线程发送过来的数据
  7.     let arr = []
  8.     // 50w行的数据
  9.     for(let i= 0; i<500000;i++){
  10.       arr.push({
  11.         name: '张' + i,
  12.         age: 18,
  13.         sex: '男',
  14.         id: '2025_12_12'+ i,
  15.         address:'XX区YYY大道' + i + '号'
  16.       })
  17.     }
  18.     // 将对象数组 arr 转换为 Excel 工作表(sheet)
  19.     const sheet  = utils.json_to_sheet(arr)
  20.     // 创建一个新的空工作簿(book)对象。工作簿是 Excel 文件的容器,可以包含多个工作表(sheet)
  21.     const workbook = utils.book_new()
  22.     // 将之前创建的工作表 (sheet) 添加到工作簿(workbook)中
  23.     utils.book_append_sheet(workbook, sheet, 'sheet1')
  24.     self.postMessage({
  25.       type: 'createExcelSuccess',
  26.       data:{
  27.         data:workbook,
  28.         message: '获取成功'
  29.       }
  30.     });
  31.   }
  32. };
复制代码
  1. this.webWorker1 = new WorkerA('./web.worker.js')
  2. this.webWorker1.terminate();
复制代码
使用worker的注意事项

1,worker不能使用window上的dom操作,也不能获取dom对象,dom相关的东西只有主线程有。worker只能做一些计算相关的操作
2,有的东西是无法通过主线程传递个子线程的。
比如:方法,dom节点,一些对象里的特殊设置(freeze,getter,setter这些)所以vue的响应式对象在传递之后就会变成普通对象
worker实际应用案例

1,将语法检查、代码压缩等任务放在 Worker 中执行
2,图像处理:比如使用Canvas处理图片,进行滤镜
worker性能优化建议

减少通信开销:避免频繁传递大量数据,必要时使用 Transferable Objects(如 ArrayBuffer)
批量处理:对于大批量任务,可批量创建 Worker 并行处理
常驻线程:对于频繁使用的 Worker,可保持常驻而非重复创建
错误处理:始终监听 onerror 事件,捕获 Worker 内部的异常
                                                                                                                               
3.jpeg
                                                微信                                                                                                本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
                        如果文中有什么错误,欢迎指出。以免更多的人被误导。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册