马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
概要
记录一下前端中听过,但是一般很少用到的前端技术 -—— Web Worker;
起首要明白为什么使用web worker。由于js 代码的实现采用的是单线程,也就说同一时刻只能做一件事,但是假如出现多个使命同时执行,那么在这段使命执行完成之前,后面的代码是不会执行的,从而导致壅闭,用户的交互会可能会出现无响应状态,影响用户体验。
什么是Web Worker
Html5提供了并规范了Web worker 这一套API。他允许JS在运行的主线程之外运行另一个线程(即Worker线程)。
使用权限
- 分享给worker运行的脚本文件,不许与主线程的脚本文件同源
- Worker是无法加载读取本地文件的,它所加载的脚本资源必须来自网络。
- Worker如今地点的全局情况变量是与主线程不一样的。
- 无法读取主线程地点网页的DOM对象
- 无法操纵document 、window 、 parent这些对象。
- Worker线程同时不能使用alert()和confirm()方法,但是可以使用XMLHttpRequest对象发出哀求,同时也可以使用setTimeout/setInterval()等API。
技术细节
代码:
- const worker = new Worker(aURL, options);
复制代码 相干的使用方法:
- worker.postMessage: 向 worker 的内部作用域发送一个消息,消息可由任何 JavaScript 对象组成
- worker.terminate: 立刻终止 worker。该方法并不会等待 worker 去完成它剩余的操纵;worker 将会被立刻停止
- worker.onmessage:当 worker 的父级吸取到来自其 worker 的消息时,会在 Worker 对象上触发 message 事件
- worker.onerror: 当 worker 出现运行中错误时,它的 onerror 事件处置惩罚函数会被调用。
- worker.addEventListener('error', function (e) {
- console.log(e.message) // 可读性良好的错误消息
- console.log(e.filename) // 发生错误的脚本文件名
- console.log(e.lineno) // 发生错误时所在脚本文件的行号
- })
复制代码 常见使用方式
- const myWorker = new Worker(URL, options);
复制代码 此中URL表示 worker 将执行的脚本的 URL(脚本文件), 即 Web Worker 所要执行的使命。
案例:
- // 主线程下创建worker线程
- const worker = new Worker('./worker.js')
- // 监听接收worker线程发的消息
- worker.onmessage = function (e) {
- console.log('主线程收到worker线程消息:', e.data)
- }
- // 向worker线程发送消息
- worker.postMessage('主线程发送hello world')
复制代码 同时的,在worker.js中:
- // self 代表子线程自身,即子线程的全局对象
- self.addEventListener("message", function (e) {
- // e.data表示主线程发送过来的数据
- self.postMessage("worker线程收到的:" + e.data); // 向主线程发送消息
- });
复制代码 在Web Worker中执行的上下文名称是self。
在Worker中引入其他运行脚本
当要在Worker中引入项目中的其他脚本时,可以使用importScripts()
- // worker.js
- importScripts("constants.js");
- // self 代表子线程自身,即子线程的全局对象
- self.addEventListener("message", function (e) {
- self.postMessage(foo); // 可拿到 `foo`、`getAge()`、`getName`的结果值
- });
- // constants.js
- const foo = "变量";
- function getAge() {
- return 25;
- }
- const getName = () => {
- return "jacky";
- };
复制代码 Vue3深度集成方案
1:Composition API实现
- // useWebWorker.js
- import { ref, onUnmounted } from 'vue';
- export default function useWebWorker(workerScript) {
- const worker = ref(null);
- const result = ref(null);
- const error = ref(null);
- const initWorker = () => {
- worker.value = new Worker(new URL(workerScript, import.meta.url));
-
- worker.value.onmessage = (e) => {
- result.value = e.data;
- };
- worker.value.onerror = (err) => {
- error.value = err;
- terminateWorker();
- };
- };
- const terminateWorker = () => {
- worker.value?.terminate();
- worker.value = null;
- };
- onUnmounted(terminateWorker);
- return {
- worker,
- result,
- error,
- initWorker,
- postMessage: (msg) => worker.value?.postMessage(msg)
- };
- }
复制代码 2:组件级应用
- <script setup>
- import { computed } from 'vue';
- import useWebWorker from './useWebWorker';
- const { result, initWorker, postMessage } = useWebWorker('./heavyTask.worker.js');
- const calculate = () => {
- initWorker();
- postMessage({ data: largeData });
- };
- // 计算属性依赖
- const formattedResult = computed(() => result.value?.toFixed(2));
- </script>
复制代码 小结
虽然在实际开辟展中用到的情况比较少,但是假如考虑到前端页面性能优化的情况,可以往该技术方向进行思索选型。
|