首页 > 编程语言 >JavaScript – Web Worker

JavaScript – Web Worker

时间:2022-10-30 11:57:28浏览次数:79  
标签:postMessage Web thread Worker self JavaScript worker 线程

前言

在上一篇 << 单线程 与 执行机制 >> 中, 我们提到了 Web Worker.

它的诞生是为了解决 JS 主线程执行耗时计算时, 导致 UI 无法及时更新的卡死现象.

它的解决思路是把同步代码异步化. 原本需要 JS 主线程执行的运算, 转交给另一条线程去完成.

这和 setTimeout 是同一个原理. 计数也不是 JS 主线程做的, 而是定时器触发线程做的.

 

参考

阮一峰 – Web Worker 使用教程

MDN – SharedWorker

 

Worker 基本使用

The Problem

假设我们有一个复杂运算 for loop 50亿次 (耗时 5 秒)

document.querySelector('h1').textContent = 'Hello World';
for (let i = 0; i < 5_000_000_000; i++) {} // 需要 5 秒钟
console.log('do something else');

如果我们让 JS 主线程来处理, 那么 UI 渲染就会慢 5 秒钟, 用户迟迟才会看见 Hello World 出现.

New Web Worker

这时我们可以开启 Web Worker, 它会创建另一条线程去处理这个 for loop. 然后我们把后续的代码变成一个 callback.

worker.js

for (let i = 0; i < 5_000_000_000; i++) {} // 需要 5 秒钟
self.postMessage('done'); // 通知主线程, 任务完成
self.close(); // 可以在子线程关闭, 也可以交由主线程关闭.

index.js

document.querySelector('h1').textContent = 'Hello World';
const worker = new Worker('./worker.js', { name: 'worker' });
// callback
worker.addEventListener('message', () => {
  console.log('do something else');
  worker.terminate(); // 关闭子线程
});

通过 addEventListener 注册 callback, 这样原本同步的代码就变成异步了.

Worker 沟通

主线程和子线程 (worker) 的沟通是通过 postMessage 和 addEventListener('message') 完成的.

postMessage 类似于 dispatchEvent 的意思.

主线程和子线程都可以 postMessage 和 listen message, 也都可以关闭子线程.

主线程也能监听子线程的错误

// index.ts – main thread
worker.postMessage('message'); // dispatch event to child thread
worker.addEventListener('message', () => {}); // listen event from child thread
worker.addEventListener('error', () => {}); // listen error from child thread
worker.terminate(); // close child thread

// worker.ts – child thread
self.postMessage('done'); // dispatch event to main thread
self.addEventListener('message', () => {}); // listen event from main thread
self.close(); // close child thread (把自己关了)

Message Data Type

// index.ts
const worker = new Worker('./worker.js', { name: 'worker' });
const file = document.querySelector('input').files[0];
file.arrayBuffer().then(arrayBuffer => {
  worker.postMessage({ value: 'value', buffer: arrayBuffer }, { transfer: [arrayBuffer] });
});

// worker.ts
self.addEventListener('message', event => {
  const { value, buffer } = event.data;
});

两个点要注意

1. postMessage 可以传对象, 但是对象会被 deep copy.

2. ArrayBuffer 也会被 copy, 有时候 size 可能会太大, 所以 postMessage 有个设置叫 transferable objects

声明 transfer 以后, ArrayBuffer 就转交给 worker 了 (no more copy), 这时主线程就不可以读取 ArrayBuffer了.

Import Script in Worker

self.importScripts('/imported-script.js');

worker 内可以 import 其它的 script.

imported-script.js 也可以调用 self.postMessage 和主线程沟通.

而 worker 和 imported-script 要沟通则是用全局变量 e.g. self.value = 'some value'.

SharedWorker

目前支持率不是很好, 以后才研究 TODO...

 

标签:postMessage,Web,thread,Worker,self,JavaScript,worker,线程
From: https://www.cnblogs.com/keatkeat/p/16840670.html

相关文章

  • javaScript简介和javaScript发展史
    *概念:一门客户端脚本语言*运行在客户端浏览器中的。每一个浏览器都有JavaScript的解析引擎*脚本语言:不需要编译,直接就可以被浏览器解析执行了*功能:*......
  • Android开发页面重定向导致WebvView.canGoBack一直返回true的解决方法
    Android开发页面重定向导致WebvView.canGoBack一直返回true的解决方法原因:打开页面A的时候重定向到页面B,页面B回退的时候回退到页面A,但是接着又重定向到页面B,所以canGoBack......
  • javascript:监控video全屏时取消静音(chrome 107.0.5304.87)
    一,js代码:<html><head><metacharset="utf-8"/><title>测试</title></head><body><divstyle="width:50%;height:100%;float:left;margin-left:-0.3px;pos......
  • VS2017 IIS 部署.net core web项目
    直接上内容: 安装IIS这个不在重复,可百度搜索到。 点击IIS查看模块:查看是否安装了AspNetCoreModule模块,如果没有安装可下载:​​http://download.microsoft.com/downlo......
  • Javaweb基础复习------Filter相关应用+登录验证案例的使用
    Filter(过滤器)基本步骤:1、定义类,实现Filter接口,并重写其所有方法2、配置Filter拦截资源的路径,在类上定义2WebFilter注解(WebFilter配置的路径,是拦截资源的路径)3、在d......
  • 1.1 仿百度Web Day1
    Day1根据自己的垃圾html+css水平写出了下面这个页面:首先,首部的超链接都能够链接上,但是不会[更多]的弹出窗口,右面的天气/设置/个人也没有做,不会怎么去调用中间......
  • Java Web
    javaweb是指,所有通过java语言编写可以通过浏览器访问的程序的总称,叫javaweb。javaweb是基于请求和影响来开发的。请求是指客户端给服务器发送的数,请求叫Request。......
  • webpack 打包原理
    目录一、为什么要使用webpack?二、什么是webpack?三、webpack核心概念1、Entry2、Output3、Chunk4、Loader5、Plugins四、webpack的核心机制Loader工作原理plugin工作原理......
  • JavaScript – event loop 事件循环, 单线程, Web Worker
    前言因为要写RxJS系列,有一篇要介绍scheduler.它需要基础的JS执行机制,于是就有了这里篇. 顺带也介绍以下WebWorker呗. 参考知乎–详解JavaScript中的......
  • 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践
    本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主。主要NuGet包:无 一、创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点1//定义Person类和ErrorInfo类2pub......