web worker在生成Excel场景下的简单使用

1.介绍

Web Workers 是 HTML5 中引入的技术,允许在浏览器中创建多线程 JavaScript 执行环境。这使得你可以在主线程之外创建一个或多个后台线程,以执行复杂的任务,而不会阻塞主线程的执行。Web Workers 对于处理需要大量计算或长时间运行的任务非常有用,因为它们可以提高网页性能和响应速度。

2.使用

当我们有任务需要大量的计算,并且不想堵塞用户的正常使用的情况,就可以选择采用webWorker

基本用法

在主进程中调用Worker()构造函数,会创建一个新的webWorker线程,构造函数的参数必须是一个脚本文件(同源限制),是无法读取本地文件的
var worker = new Worker('work.js');

在项目中,可以通过以下方式设置脚本文件:


1.选择直接将文件放置服务器对应静态目录下

2.通过Blob将字符串转化成 Blob对象,再通过URL.createObjectURL生成对象的URL,供Worker()构造函数使用(不推荐)

javascript 复制代码
new Worker(
    URL.createObjectURL(
        new Blob([
            `
            console.log('hello world');
      `,
        ])
    )
)

3.通过打包工具创建(推荐)

webpack中可以使用worker-loader去处理 xxx.worker.js 文件

vite中不需要任何工具:

通过import MyWorker from "./utils/uploadExcel.js?worker"在引入时追加?worker

也可通过 new Worker(new URL('./utils/uploadExcel.js?raw', import.meta.url))来获取文件的原始内容的方式引入。


基本的使用教程,可以去看一下阮一峰老师的博客,推荐一下,这里就不水字数了
Web Worker 使用教程 - 阮一峰的网络日志

3.场景演示

下面我将会简单演示一下webWorker在前端生成Excel的场景下的使用

在主进程页面中,创建一个按钮去触发事件,接收到worker线程中传递的数据将其下载下来

vue 复制代码
<script setup>
// 这样的方式也可,但importScripts会报错,原因未知
// import MyWorker from "./utils/uploadExcel.js?worker"
// const worker = new MyWorker()
const worker = new Worker(new URL('./utils/uploadExcel.js?raw', import.meta.url))
// 监听消息
worker.onmessage = ({ data }) => {
  const a = document.createElement("a");
  a.download = `${new Date().toLocaleTimeString()}.xlsx`;
  a.href = URL.createObjectURL(new Blob([data], { type: "application/octet-stream" }));
  a.click();
}
const getExcel = () => {
  worker.postMessage("start")
}
</script>
<template>
  <div>
    <button type="button" @click="getExcel">点击下载Excel</button>
  </div>
</template>

在worker进程中

javascript 复制代码
self.importScripts('https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.15.3/xlsx.core.min.js');
const getHq = () => {
  return new Promise((res) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "http://localhost:3002/list", true);
    xhr.onload = () => {
      if (xhr.status === 200) {
        const responseData = xhr.responseText;
        res(responseData)
      } else {
        console.error("请求失败,状态码:" + xhr.status);
      }
    };
    xhr.send();
  })
}
onmessage = function (event) {
  const { data } = event
  if (data === "start") {
    let startTime = new Date();
    getHq().then(res => {
      console.log("开始整理数据-"+startTime);
      res= JSON.parse(res);
      const ws = XLSX.utils.aoa_to_sheet(res.data, { dense: true });
      const wb = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(wb, ws);
      postMessage(XLSX.write(wb, {type: 'array', bookType: 'xlsx', bookSST: true, compression: true}));
      let endTime = new Date()
      console.log("结束正在将数据发送给主线程-"+endTime)
      console.log(`传递总耗时间${Math.floor((endTime - startTime )/ 1000)}`);
    });
  }
}

在网络上随便找的xlsx.js文件路径通过importScripts放入worker线程中加载,在webWorker中也可以发起请求,在上面的代码中通过原生的XML进行请求后端数据,当然这里也可以使用fetch。接收到数据将其发送给主线程。

javascript 复制代码
// 引入 Express.js 模块
const express = require('express');
// 创建 Express 应用程序
const app = express();
// 创建一个路由,响应根路径的 GET 请求
app.get('/list', (req, res) => {
    const ListData = new Array(100000).fill(new Array(20).fill("这是一段文本"));
    res.json({data:ListData});
});
// 启动服务器并监听端口
const port = 3001;
app.listen(port, () => {
    console.log(`Express app listening on port ${port}`);
});

启动一个express,模拟后端发送数据。当然你也可以通过主线程将数据传递进worker线程用来填充Excel的数据,这样一个简单的Excel下载就完成了。

yaml 复制代码
开始整理数据-Wed Nov 08 2023 18:07:36 GMT+0800 (香港标准时间)
结束正在将数据发送给主线程-Wed Nov 08 2023 18:07:43 GMT+0800 (香港标准时间)
传递总耗时间7

结束语

webWorker优势

独立运行,沙箱一样的隔离机制,异步并行计算

webWorker劣势

兼容性差,没有办法访问dom,编码成本高,通过拷贝的方式传输数据(js允许主线程向worker线程直接转移二进制数据,这个除外)

参考资料

Web Worker 使用教程 - 阮一峰的网络日志
使用 Web Workers - Web API 接口参考 | MDN

相关推荐
爱喝白开水a1 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
董世昌411 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
吃杠碰小鸡2 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone2 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09012 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农3 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king3 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
夏幻灵4 小时前
HTML5里最常用的十大标签
前端·html·html5
Mr Xu_4 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝4 小时前
RBAC前端架构-01:项目初始化
前端·架构