JavaScript – Web Worker
前言
在上一篇 << 单线程 与 执行机制 >> 中, 我们提到了 Web Worker.
它的诞生是为了解决 JS 主线程执行耗时计算时, 导致 UI 无法及时更新的卡死现象.
它的解决思路是把同步代码异步化. 原本需要 JS 主线程执行的运算, 转交给另一条线程去完成.
这和 setTimeout 是同一个原理. 计数也不是 JS 主线程做的, 而是定时器触发线程做的.
参考
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 太大 copy 会很慢, 所以 postMessage 有个设置叫 transferable objects
声明 transfer 以后, ArrayBuffer 就转交给 worker 了 (no more copy, use cut instead), 这时主线程就不可以再读取 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...

JavaScript – Web Worker的更多相关文章
- 深入理解javascript异步编程障眼法&&h5 web worker实现多线程
0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 1 2 3 4 ...
- JavaScript多线程之HTML5 Web Worker
在博主的前些文章Promise的前世今生和妙用技巧和JavaScript单线程和浏览器事件循环简述中都曾提到了HTML5 Web Worker这一个概念.在JavaScript单线程和浏览器事件循环简 ...
- Web Worker javascript多线程编程(一)
什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...
- Web Worker javascript多线程编程(二)
Web Worker javascript多线程编程(一)中提到有两种Web Worker:专用线程dedicated web worker,以及共享线程shared web worker.不过主要讲 ...
- javascript 多线程Web Worker不引用外部js文件的方法
最近在Android开发中 Webview通过调用JavascriptInterface的方式与App交互 在交互的过程中,有些App上的操作时间会比较长,Web中调用的话会造成程序假死的情况 于是想 ...
- 【转向Javascript系列】深入理解Web Worker
本文首发在alloyteam团队博客,链接地址http://www.alloyteam.com/2015/11/deep-in-web-worker/ 上一篇文章<从setTimeout说事件循 ...
- 【转】Web Worker javascript多线程编程(一)
原文:https://www.cnblogs.com/peakleo/p/6218823.html -------------------------------------------------- ...
- 过段时间逐步使用HTML5新增的web worker等内容
想来快2017年了,2013年前的手机应该很少有人用了,以后逐渐使用HTML5新增的高级API吧. 先把web worker的内容再熟悉一下,因为微软虚拟学院的'面向有经验开发人员的 JavaScri ...
- web Worker使js实现‘多线程’?
大家都知道js是单线程的,在上一段js执行结束之前,后面的js绝对不会执行,那么为什么标题说js实现‘多线程’,虽然说加了引号,可是标题也不能乱写不是,可恶的标题党? 姑且抛开标题不说,先说我们经常会 ...
- HTML5:web socket 和 web worker
a:hover { cursor: pointer } 做练习遇到了一个选择题,是关于web worker的,问web worker会不会影响页面性能?补习功课之后,答案是不会影响. 查阅了相关资料学 ...
随机推荐
- [oeasy]python0135_变量名与下划线_dunder_声明与赋值
变量定义 回忆上次内容 变量 就是 能变的量 上次研究了 变量标识符的 规则 第一个字符 应该是 字母或下划线 合法的标识符可以包括 大小写字母 数字 下划线 还研究了字符串(str)的函数 ...
- Swift开发基础08-高阶函数
高阶函数是指接受其它函数作为参数,或者返回其它函数的函数.Swift 提供了许多内置的高阶函数,这些函数在处理集合类型数据(如数组.集合等)时尤其有用.常见的高阶函数包括 map.filter.red ...
- C# 对象复制三种方法效率对比——反射、序列化、表达式树
1.需求 在代码中经常会遇到需要把对象复制一遍,或者把属性名相同的值复制一遍. 比如: public class Student { public int Id { get; set; } publi ...
- 2024 暑假友谊赛 1 (7.13)zhaosang
A-A https://vjudge.net/contest/638765#problem/A 一开始贪心做不出来,后面发现是dp找到转移方程即可,01dp问题 代码如下 #include <b ...
- Django 解决跨域访问API失败问题
解决跨域访问API失败问题 By:授客 QQ:103355122 实践环境 Win 10 Python 3.5.4 Django-2.0.13.tar.gz 官方下载地址: https://w ...
- jwt redis,微信登陆知识复习 uniapp 请求封装,统一异常处理 相关, HutoolDemo工具介绍)
第三节 后台布局搭建,代码可以人工智能来写,但是环境初步搭建需要我们先建起来,所以以下记录快带搭建的过程, 思路: 后台首页的搭建 第一 用到了element--UI 自带的页面布局组件,它就 ...
- python raise异常处理
python raise异常处理 一般最简单的异常处理是try except: try: f = open('test.txt') except Exception as e: print(e) f ...
- 【Maven】下载安装(Linux)
Maven官网下载地址: http://maven.apache.org/download.cgi 点选这个压缩包 wget或者上传都行 解压 tar -zxvf apache-maven-3.6.3 ...
- 新手入门深度学习:在不使用Google的情况下如何在国内获得免费的算力 —— 算力共享,驱动人工智能创新的新引擎
分享链接地址: 算力获新生 | 算力共享,驱动人工智能创新的新引擎
- 如何租GPU:一个价格还算OK的云GPU服务器租赁公司
一个价格还算OK的云GPU服务器租赁公司. 地址: https://www.gpushare.com/