多线程的JavaScript: Web Worker

Web Worker是 HTML5推出的标准

Web Workers makes it possible to run a script operation in a background thread separate from the main execution thread of a web application.

优点

允许 JavaScript 脚本创建多个线程,从而充分利用 CPU 的多核计算能力,不会阻塞主线程 (一般指 UI 渲染线程) 的运行, 兼容性良好,基本覆盖了所有主流浏览器

局限

Web Worker本质上没有突破JS的单线程的性质,Web Worker脚步不能直接操作DOM节点, 不能使用绝大多数的BOM API。 上下文环境是DedicatedWorkerGlobalScope 而不是Window。 运行Worker的实际上是一个沙箱,跑的是与主线程完全独立的JavaScript文件。

使用场景

作为主线程的附属,完成高 CPU 计算型的数据处理,再通过线程间通信将执行结果传回给主线程。在整个过程中,主线程仍然能正常地相应用户操作,从而很好地避免页面的卡顿现象。

具体场景:

  • 预加载数据:可以使用Worker提前加载数据,实现秒开
  • 拼写检查
  • 加密: 有时候加密会非常耗时。
  • 渐进式网络应用PWA: 例如:通过与IndexDB的整合实现离线访问

如何使用

uniapp 平台web Worker使用

新建

const worker = new Worker("./worker.js");

通信

// main.js
const worker = new Worker("./worker.js");

// 主线程发送消息
worker.postMessage({ data: '黄某还是挺不错的' });

// 主线程接收消息
worker.onmessage = (e) => {
    const { data } = e;
    if (!data) return;
    console.log(data);
}
// worker.js
// worker线程接收消息
self.addEventListener('message', (e) => {
    const { data } = e;
    if (!data) return;
    // worker线程发送消息
    self.postMessage({data: 'worker received data'})
});

注: Worker 中,this.xx, self.xx 与直接使用 xx,其作用域都指向 worker 的全局变量 DedicatedWorkerGlobalScope ,可以互换

销毁

两种方式

// 第一种:主线程通知销毁
// main.js
worker.terminate();

// worker.js
self.close();

Worker加载脚本

importScripts('script1.js');
// 或者可以加载多个
importScripts('script1.js', 'script2.js');

错误处理

主线程可以监听Worker是否发生错误

worker.onerror(function (event) {
  console.log([
    'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
  ].join(''));
});

// 内部也可以监听error事件
worker.addEventListener('error', function (event) {
  // ...
});

参考:

posted @ 2020-12-11 01:04  weiQLog  阅读(411)  评论(0编辑  收藏  举报