一文读懂JavaScript多线程Web Worker

 更新时间:2025年11月13日 11:30:52   投稿:wdc  
HTML5就提出了web Worker标准,表示JavaScript允许有多个线程,但是子线程完全受主线程的控制,并且子线程不能操作DOM,只有主线程可以操作DOM

前言

大家都知道,JavaScript是单线程的,也就是说,所有的任务只能在一个线程上完成,一次只能做一件事。前面的任务如果没有完成,后面就只能等着。所以,HTML5就提出了web Worker标准,表示JavaScript允许有多个线程,但是子线程完全受主线程的控制,并且子线程不能操作DOM,只有主线程可以操作DOM。所以 Web Worker 的最佳使用场景是执行一些开销较大的数据处理或计算任务,接下来我们就来具体的了解一下这个东西吧~

正文

什么是Web Worker ?

Web Worker 是HTML5标准的一部分,这一规范定义了一套API,它允许一段JavaScript程序运行在主线程之外的另外一个线程中。

值得注意的是, Web Worker 规范中定义了两类工作线程,分别是专用线程Dedicated Worker和共享线程 Shared Worker。其中,Dedicated Worker只能为一个页面所使用,而Shared Worker则可以被多个页面所共享。

如何使用Worker?

使用的时候需要注意的几个地方

  • 同源限制
    分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。
  • DOM限制
    Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。
  • 通信
    Worker 线程和主线程不在同一个上下文环境,所以它们不能直接通信,必须通过发布订阅消息完成。
  • 脚本限制
    Worker 线程内不能执行alert()方法和confirm()方法,但是可以使用 XMLHttpRequest 对象发送 AJAX 请求。
  • 文件限制
    Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。

如何创建一个Worker?

Worker构造函数,第一个参数是脚本的网址(必须遵守同源政策),该参数是必需的,且只能加载 JS 脚本,否则报错。
第二个参数是配置对象,该对象可选。它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程。

例如创建一个Worker

const worker = new Worker('worker.js');

主线程与子线程如何通信?

基本原理就是在当前的主线程中加载一个只读文件来创建一个新的线程,两个线程同时存在,且互不阻塞,并且在子线程与主线程之间提供了数据交换的接口postMessage和onmessage。

例如,向Worker子线程发送消息

// 第一种传递方式
worker.postMessage('我是主线程');

// 第二种传递方式
worker.postMessage({
  // ArrayBuffer object 
  input: buffer
}, [buffer]);

worker.postMessage()方法的参数,就是主线程传给子线程 Worker 的数据。它可以是各种数据类型,包括二进制数据。

接收子线程Work发回的消息

worker.onmessage = function (event) {
  console.log('子线程的消息:' + event.data)
}

worker.js子线程向主线程发送消息

self.postMessage('我是子线程')

接收主线程发来的消息

self.onmessage = function (event) {
  console.log('主线程的消息:' + event.data)
}

self代表子线程自身,即子线程的全局对象。

以下是主线程与子线程的常用API

主线程中的,worker表示是 Worker 的实例:

  • worker.postMessage
    主线程往worker线程发消息,消息可以是任意类型数据,包括二进制的数据
  • worker.terminate
    主线程关闭worker线程
  • worker.onmessage
    指定worker线程发消息时的回调
    也可以通过 worker.addEventListener('message', cb) 的方式
  • worker.onerror
    指定worker线程发生错误时的回调
    同样也可以 worker.addEventListener('error', cb)

Worker线程中全局对象为 self,代表子线程自身,这时this指向self:

  • self.postMessage
    worker线程往主线程发消息,消息可以是任意类型数据,包括二进制数据
  • self.close
    worker线程关闭自己
  • self.onmessage
    指定主线程发worker线程消息时的回调
    也可以self.addEventListener('message', cb)
  • self.onerror
    指定worker线程发生错误时的回调
    也可以 self.addEventListener('error', cb)
  • self.name
    Worker 的名字。该属性只读,由构造函数指定。

载入工具函数

importScripts('work1.js', 'work2.js', ...)

importScripts是同步方法,一旦importScripts方法返回就可以开始使用载入的脚本,而不需要回调函数。

共享线程 SharedWorker

共享线程是为了避免线程的重复创建和销毁过程,降低了系统性能的消耗,共享线程SharedWorker可以同时有多个页面的线程链接。
使用SharedWorker创建共享线程,也需要提供一个javascript脚本文件的URL地址或Blob,该脚本文件中包含了我们在线程中需要执行的代码,如下:

const sharedworker = new SharedWorker("sharedworker.js");

共享线程也使用了message事件监听线程消息,但使用SharedWorker对象的port属性与线程通信如下。

sharedworker.port.onmessage = function (event) {
  console.log(event.data)
}

也可以使用SharedWorker对象的port属性向共享线程发送消息

sharedworker.port.postMessage('Hello World');

到此这篇关于一文读懂JavaScript多线程Web Worker的文章就介绍到这了,更多相关JavaScript多线程Web Worker内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaScript在XHTML中的用法详解

    JavaScript在XHTML中的用法详解

    下面的代码在HTML中是有效的,但在XHTML中则是无效的接下来为大家介绍下JavaScript在XHTML中的用法,感兴趣的朋友可以参考下哈
    2013-04-04
  • 浅析offsetLeft,Left,clientLeft之间的区别

    浅析offsetLeft,Left,clientLeft之间的区别

    这篇文章主要是对offsetLeft,Left,clientLeft之间的区别进行了详细的分析介绍,需要的朋友可以过来参考下想,希望对大家有所帮助
    2013-11-11
  • 浅谈JavaScript 框架分类

    浅谈JavaScript 框架分类

    本文简单介绍了javascript的5种框架分类,以及框架特征的相关资料,有需要的童鞋们可以参考下
    2014-11-11
  • 有关javascript的性能优化 (repaint和reflow)

    有关javascript的性能优化 (repaint和reflow)

    本篇文章,小编将为大家介绍,有关javascript的性能优化(repaint和reflow),有需要的朋友可以参考一下
    2013-04-04
  • Java Mybatis框架入门基础教程

    Java Mybatis框架入门基础教程

    MyBatis是一款一流的支持自定义SQL、存储过程和高级映射的持久化框架。MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去 设置参数和获取检索结果,对MyBatis感兴趣的小伙伴们可以参考一下
    2015-09-09
  • JavaScript的对象和包装类你了解多少

    JavaScript的对象和包装类你了解多少

    这篇文章主要为大家详细介绍了JavaScript的对象和包装类,使用数据库,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 每日十条JavaScript经验技巧(一)

    每日十条JavaScript经验技巧(一)

    本文是每日十条JavaScript经验技巧系列文章的第一篇,给大家汇总介绍一些在JavaScript使用过程中的注意事项,非常的简单,都是个人在平时项目中的一点小小的总结,希望对大家能够有所帮助
    2016-06-06
  • javascript工具库代码

    javascript工具库代码

    这段时间用到的javascript工具库 工作中,自己边用边写的,需要的朋友可以参考下
    2012-03-03
  • javascript数字时钟示例分享

    javascript数字时钟示例分享

    这篇文章主要介绍了javascript数字时钟示例,需要的朋友可以参考下
    2014-04-04
  • JavaScript基础之Array forEach使用示例

    JavaScript基础之Array forEach使用示例

    这篇文章主要为大家介绍了JavaScript基础之Array forEach使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12

最新评论