一文读懂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回调函数

    理解javascript回调函数

    这篇文章主要介绍了理解javascript回调函数的相关资料,需要的朋友可以参考下
    2014-12-12
  • javaScript arguments 对象使用介绍

    javaScript arguments 对象使用介绍

    函数体内可以通过 arguments 对象来接收传递进来的参数,下面有个不错的示例,大家可以感受下
    2013-10-10
  • javascript实现滑动解锁功能

    javascript实现滑动解锁功能

    这篇文章主要介绍了javascript实现滑动解锁功能的方法及示例,效果非常棒,需要的朋友可以参考下
    2014-12-12
  • JavaScript函数模式详解

    JavaScript函数模式详解

    文章对javascript的四种函数模式进行了详细的解释,并附上示例,方便小伙伴们理解并应用,希望对大家能有所帮助。
    2014-11-11
  • JavaScript中的数据类型介绍

    JavaScript中的数据类型介绍

    这篇文章介绍了JavaScript中的数据类型,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • 快速解决Canvas.toDataURL 图片跨域的问题

    快速解决Canvas.toDataURL 图片跨域的问题

    出现Canvas.toDataURL 图片跨域问题怎么解决呢?下面小编就为大家带来一篇Canvas.toDataURL 图片跨域问题的快速解决方法。一起跟随小编过来看看吧
    2016-05-05
  • ajax与jsonp的区别及用法

    ajax与jsonp的区别及用法

    在本篇文章里我们给大家分享了ajax与jsonp的区别的相关知识点内容,有需要的朋友们可以学习下。
    2018-10-10
  • actionscript与javascript的区别

    actionscript与javascript的区别

    actionscript是flash的脚本语言,目前已经由adobe公司升级到3.0版本,成为了真正意义的oop语言,JavaScript是由netscape工程师设计完成的一门脚本语言,用于web开发的前端脚本
    2011-05-05
  • 关于uni-app页面Page和组件Component生命周期执行的先后顺序

    关于uni-app页面Page和组件Component生命周期执行的先后顺序

    这篇文章主要介绍了关于uni-app页面Page和组件Component生命周期执行的先后顺序,文中提供了具体的代码,还不清楚的朋友可以来学习一下
    2023-04-04
  • javascript编程必备_JS语法字典

    javascript编程必备_JS语法字典

    网友整理的107条javascript语法字典,方便经常使用js编程的朋友
    2008-06-06

最新评论