面试使人进步!!!
在大厂佬们的碾压下接触到了目前工作中没有遇到的新api和新思路以及解决方案。
今天就来说说这个新的api web Worker。以下是MDN原话
指的是一种可由脚本创建的后台任务,任务执行中可以向其创建者收发信息。要创建一个 Worker?,只须调用?Worker(URL)? 构造函数,函数参数 `URL` 为指定的脚本。Worker?也可以创建新的 Worker,当然,所有 Worker 必须与其创建者同源。
很明显了就是让我们可以开启一个新的进程来处理js。js是采用的是单线程模型,代码从上往下执行如果js任务中间存在较大的数据计算那么势必会阻塞js的运行以及页面的渲染,那么这时候web worker就是一个很好的解决方案,可以将这部分数据计算的代码放到web worker中进行处理等待处理完成后在通过通信的方式告知js线程。下面是一个简单的demo(vite-react)
import React, { useEffect, useState } from "react";
export default (): JSX.Element => {
const [w, setW] = useState<Worker>()
const startWorker = () => {
setW(new Worker("http://localhost:3322/front/worker.js"))
}
function stopWorker() {
if (!w) return
w.terminate(); // 终止进程运行,下回启动重头开始
}
useEffect(() => {
if (!w || !!w.onmessage) return
w.onmessage = function (event) {
// 通过postMessage和onMessage进行线程之间的通信
console.log("通知来了", event);
};
}, [w])
return <div>
web-worker
<button onClick={startWorker}>开始</button>
<button onClick={stopWorker}>结束</button>
</div>;
};
worker.js
var i = 0;
// confirm(1) 错误
// alert(1) 错误
// console.log(window, document) 错误
function a() {
i = i + 1;
console.log(i)
postMessage(i); // 进程间通信
setTimeout(a, 1000);
}
a();
需要注意的地方:
1.new Worker接收的参数是和当前环境同一域名下(同源策略)的js文件并且不能是file://协议要是http协议。因此我将文件放到和vite的index.html同一目录下启动服务直接就能访问。
2.worker进程中不能执行alert和confirm来打端主进程但是可以执行ajax网络请求。
3.worker进程无法使用window和document对象同时也获取不到dom。
|