webWorker基本用法

我们都知道js是一个单线程的语言,当线程堵塞时,可能会导致页面无法正常交互,如一些复杂的可视化处理。即使是异步处理,也只是将其暂存到任务队列中去,等主线程执行完后依然会从任务队列中取过去。

为此,js提供了一种多线程效果的处理方式--webWorker,下面来用一段实力来展示:

基本示例(这里在一个vue项目中展示)

1.先创建一个webWorker对应的js文件

注:由于webworker构造函数接收的路径需要是线上的地址,因此在开发过程中可以放到public文件夹中(如example.js)这样,通过 项目启动地址+文件名即可访问该文件。

这样通过http://127.0.0.1:5173/example.js 即可访问该文件,并看到该文件内容:

2.在想要使用webWorker的方法中,创建一个webWorker对象(参数为上面的地址,本示例中的http://127.0.0.1:5173/example.js);不用本地地址的原因后续会说。

html 复制代码
<button @click="startWebWorker">点我触发webWorker</button>
javascript 复制代码
startWebWorker() {
  // 创建一个webWorker对象
  let myWorker = new Worker("http://127.0.0.1:5173/example.js")
},

这样,当点击此按钮时,会调用example.js中的脚本内容输出"hello world"。

3.postMessage方法:

通过postMessage可以向webWorker中传递参数(不可为函数):

javascript 复制代码
startWebWorker() {
  // 创建一个webWorker对象
  let myWorker = new Worker("http://127.0.0.1:5173/example.js")
  myWorker.postMessage("hello webWorker");
},

4.接收传过来的数据:

这里可以通过监听message事件来获取到数据。(webWorker对应文件中使用self进行postMessage等相关操作)

example.js中:

javascript 复制代码
// console.log("hello world")
self.addEventListener("message", (res) => {
    console.log(res.data); // 输出 hello webWorker
})

(ps,也可以使用self.onmessage来获取)

5.反向传递信息

其原理与上面的类似,同样使用postMessage,与监听message来实现:

示例vue文件中的方法:

javascript 复制代码
startWebWorker() {
  // 创建一个webWorker对象
  let myWorker = new Worker("http://127.0.0.1:5173/example.js")
  myWorker.postMessage("发送的信息:hello webWorker");
  myWorker.addEventListener("message", (res) => {
    console.log("返回的信息:" + res.data)
  })
},

example.js中:

javascript 复制代码
// console.log("hello world")
self.addEventListener("message", (res) => {
    console.log(res.data); // 输出 hello webWorker
    self.postMessage("nice to meet you too!");
})

结果:

6.补充:

比如说 public/example.js 中想要使用 public/test.js 中的方法:

public/test.js:

javascript 复制代码
function testFun() {
    console.log('我是testFun')
}

public/example.js:(这里直接这样引用会报错)

javascript 复制代码
import "./test.js"
testFun();

需改为以下引发:

javascript 复制代码
// import "./test.js"
importScripts("http://127.0.0.1:5173/test.js")
testFun()

当然有一种例外,就是test.js中使用的es6的module:

public/test.js:

javascript 复制代码
export function testFun() {
    console.log('我是testFun')
}

报错:Uncaught SyntaxError: Cannot use import statement outside a module

此时就不能用importScripts了,需要在创建webWorker对象时声明type为module

示例vue文件中的 创建一个webWorker对象 部分:

javascript 复制代码
// 创建一个webWorker对象
let myWorker = new Worker("http://127.0.0.1:5173/example.js", {
    type: "module"
})

public/example.js:

javascript 复制代码
import { testFun } from "./test.js"
// importScripts("http://127.0.0.1:5173/test.js")
testFun()

这样就生效了。

webWorker注意事项

1.webWorker文件中的方法不可操作节点。

2.postMessage方法不可传递function方法。

3.new Worker参数不可为本地文件,可使用线上地址(如发布出去)。

4.在webWorker文件中若想使用第三方库的方法(如导出excel),可以通过cdn引入,或者将node_modules关键文件以同样方式(放入public或发布)引入。

单线程堵塞处理实例

1.堵塞简单示例,最简单的,遍历百亿次(电脑好可以更多,根据务必电脑情况斟酌):

html 复制代码
<button @click="startWebWorker">遍历一亿次</button>
信息:<input />
javascript 复制代码
startWebWorker() {
  let total = 0
  for(let i = 0; i< 10000000000; i++) {
    total++;
  }
  console.log("结果是:" + total);
},

在结果输出前,你会发现输入框处于无法交互状态,整个页面都被堵塞所影响了,这个是异步也很难解决的问题。

因此,这里可以借助webWorker来实现:

javascript 复制代码
startWebWorker() {
  // 创建一个webWorker对象
  let myWorker = new Worker("http://127.0.0.1:5173/example.js");
  myWorker.postMessage("开始遍历");
  myWorker.onmessage = (res) => {
    console.log("结果是:" + res.data);
  }
},

public/example.js:

javascript 复制代码
self.addEventListener("message", (res) => {
    if(res.data == "开始遍历") {
        let total = 0
        for(let i = 0; i< 10000000000; i++) {
          total++;
        }
        self.postMessage(total)
    }
})

这样,堵塞就因 webWorker多线程 的缘故而不会影响页面(如:输入框)的正常交互了。

希望本文会对您有所帮助 ^_^ ~

相关推荐
王哈哈^_^40 分钟前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie1 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic2 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
cy玩具2 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
customer083 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
清灵xmf3 小时前
TypeScript 类型进阶指南
javascript·typescript·泛型·t·infer
小白学大数据3 小时前
JavaScript重定向对网络爬虫的影响及处理
开发语言·javascript·数据库·爬虫
qq_390161773 小时前
防抖函数--应用场景及示例
前端·javascript
334554324 小时前
element动态表头合并表格
开发语言·javascript·ecmascript