JavaScript的多线程(工作线程)简介

首先声明,标题写成多线程主要目的是吸引眼球赚点击量,程序员一般看见多线程就会肾上腺素激升,你懂的。。。

其实更精确的定义是工作线程worker thread,本篇会详细为何起名叫工作线程worker thread,而非其他语言中的多线程multi thread,两者有些许差别。

JavaScript原本是单线程的,一次只能处理一件事。如果处理数组占据大量时间,用户点击可能就没反应了,或页面刷新很慢,影响用户体验。

HTML5之后可以新建一个工作线程来处理数组,确保之后的事情能顺利完成。

工作线程大致定义如下:

由一个单独的JavaScript文件定义。要让工作线程工作,浏览器会发送一个消息,工作线程收到消息开始工作。完成工作后发回消息给浏览器。

1.HTML中加载的js相当于主线程:

<script src="js/myThread.js"></script>    //可以将HTML中加载的myThread.js理解为主线程

2.定义个worker.js,内容可以暂时为空。(为定义工作线程做准备)

3.主线程中定义工作线程,发送消息让工作线程开始工作,定义onmessage和onerror回调函数,分别处理工作线程成功或失败完成工作的事件

window.onload = function() {                        //HTML页面加载时运行代码
	var worker = new Worker("js/worker.js");    //将第2步新建的空的<span style="color:black;"><span style="color:black;">worker.js</span></span>定义成工作线程(※1)
	worker.postMessage("startwork");            //主线程向工作线程发送消息(※2)

	worker.onmessage = function(event) {        //工作线程成功完成工作后的回调函数(※3)
            document.getElementById("output").innerHTML = event.data;
	}

	worker.onerror = function(error) {          //工作线程完成工作失败后的回调函数(※3)
		document.getElementById("output").innerHTML =
			"There was an error in " + error.filename +
			" at line number " + error.lineno +
			": " + error.message;
	};
}

※1:只能用一个js文件创建工作线程,而不能用函数。因为规定工作线程不能访问DOM,如果向Worker构造函数传入一个函数,该函数可能包含DOM或主JavaScript代码的引用,就违反规则。因此工作线程的设计者选择的做法是只能传递一个js文件的URL

※2:消息可以是一个简单的字符串,也可以更复杂如worker.postMessage([1,2,3,4]);数组,worker.postMessage({“message”:“ping”,
“count”: 5});JSON对象。但不能worker.postMessage(func);发送函数,理由见※1。

※3:回调函数的参数Event对象:我们只对data和target属性感兴趣,data属性包含工作线程发送的消息,target属性是发出这个消息的工作线程的引用,方便我们知道来自哪个工作线程

4.实现worker.js

onmessage = function(event) {
	if (event.data == "startwork") {    //根据主线程发来的消息,做相应的处理
		......                      //此处省略50行业务相关的处理工作
		postMessage("done!");       //工作完成,回发消息通知主线程,主线程的onmessage方法将被触发
	} else {
		postMessage("Are you sleepwalking now?");
	}
}

工作线程注意点:

1.上面的※1已经说明过了,这里再啰嗦一遍:

工作线程无法访问浏览器代码能够访问的很多运行时的对象,如DOM或主代码中的所有变量和函数。但可以访问localStorage或做出XMLHttpRequest请求。

之所以如此设计,是因为必须保证只有一个线程能访问DOM,否则多个线程并发修改DOM会很容易导致DOM处于一种不一致的状态。

想象一下线程A为某个DOM元素增加子DOM元素,线程B删除该DOM元素。而线程之间无法保证运行顺序,如果线程B先完成,线程A取DOM元素时将会出错。

现在明白工作线程和传统意义上的多线程的区别了吧,工作线程相当于一个二等公民。

2.主线程向工作线程发送的消息对象,不会成两者间的共享对象。工作线程会得到对象的副本,工作线程中对副本的修改不会影响到主线程中该对象,工作线程发出的对象也是如此,主线程只能得到该对象的副本

何时使用工作线程:

学习了工作线程的基本原理和技术后,请不要滥用它。因为工作线程的负荷是很重的,通常数据量不大时压根没必要使用工作线程。

但在页面做图像处理时就非常有用了,不用工作线程的话,加载显示Mandelbrot分形图页面的速度将难以忍受:

时间: 2024-10-13 14:20:35

JavaScript的多线程(工作线程)简介的相关文章

【JavaScript】吃饱了撑的系列之JavaScript模拟多线程并发

前言 最近,明学是一个火热的话题,而我,却也想当那么一回明学家,那就是,把JavaScript和多线程并发这两个八竿子打不找的东西,给硬凑了起来,还写了一个并发库concurrent-thread-js.尴尬的是,当我发现其中的不合理之处,即这个东东的应用场景究竟是什么时,我发现我已经把代码写完了. ??注意! 本文中的线程指的都是用JS异步函数模拟的“假线程”,不是真正意义上的多线程,请不要误解?? github地址 https://github.com/penghuwan/concurren

多线程并行计算连载----简介和基础概念

一.背景: 最近对多核条件下的并行.并发编程感兴趣,专门学习了一下.在此将学习后梳理的知识点写上来,若有不妥之处,望指正. 环境:因为Java语言对多线程的支持度较好,因此在介绍的时候选用Java来表达相关概念. 内容: 1.并行并发的概念.基础知识,Java中基础语法的介绍 2.并行程序: 多线程条件下的数组求和算法:介绍普通算法和fork-join 框架在此处的应用:及分而治之的思想 ... 3.并发程序: ... ... 二.并行.并发区别 并行:把一个大的任务,分解成多个子任务,在多个C

003-Web Worker工作线程

一.关于Web Worker工作线程 HTML5几个优势特性里,就包括了Web Worker,这货可以了解为多线程,正常形况下,浏览器执行某段程序的时候会阻塞直到运行结束后在恢复到正常状态,而HTML5的Web Worker就是为了解决这个问题. 允许JavaScript创建多个线程,但是子线程完全受主线程控制,且不得操作DOM. 所以它能解决两个问题:一.解决程序阻塞问题:二.提升效率. 二.示例 常测试效率最常用的无非就是fibonacci了,我们也来个fibonacci性能测试. var

分布式缓存系统 Memcached 工作线程初始化

Memcached采用典型的Master-Worker模式,其核心思想是:有Master和Worker两类进程(线程)协同工作,Master进程负责接收和分配任务,Worker进程负责处理子任务.当各Worker进程将各个子任务处理完成后,将结果返回给Master进程,由Master进程做归纳和汇总. 工作示意图如下所示: 其中每个工作线程维护一个连接队列,以接收由主线程分配的客户连接:同时每个工作线程维护一个Libevent实例,以处理和主线程间的管道通信以及和客户连接间的socket通信事件

深入理解IIS的多线程工作机制

首先让我们来看看IIS里面的这2个数字:最大并发连接数,队列长度.先说这2个数字在哪里看. 最大并发连接数:在IIS中选中一个网站,右键网站名称,在右键菜单中找到并点击[管理网站]->[高级设置].打开对话框如下图: 队列长度:在IIS中选中[应用程序池],在应用程序池列表中,右键你想查看的,在右键菜单中选择[高级设置].打开如下对话框: 这两个数字表面上看是影响我们站点的并发处理能力的,但是具体是如何影响一个网站的并发处理能力的呢?要完全理解IIS的并发处理能力,除了这2个数字,实际上还有一个

Java多线程之线程结束清理

该事例说明了清理工作必须要放在finally块中 package Thread.Interrupting; import java.util.concurrent.TimeUnit; class NeedsCleanup { private final int id; public NeedsCleanup(int ident) { id = ident; System.out.println("NeedsCleanup " + id); } public void cleanup()

多线程之线程同步

多线程内容大致分两部分,其一是异步操作,可通过专用,线程池,Task,Parallel,PLINQ等,而这里又涉及工作线程与IO线程:其二是线程同步问题,鄙人现在学习与探究的是线程同步问题. 通过学习<CLR via C#>里面的内容,对线程同步形成了脉络较清晰的体系结构,在多线程中实现线程同步的是线程同步构造,这个构造分两大类,一个是基元构造,一个是混合构造.所谓基元则是在代码中使用最简单的构造.基元构造又分成两类,一个是用户模式,另一个是内核模式.而混合构造则是在内部会使用基元构造的用户模

窗体和线程漫谈之工作线程怎样将数据的处理结果显示到窗体

前言 原本这篇博客的标题叫<窗体和线程漫谈>,但想来想去确实不太合适.由于我确实没有写关于窗体和线程的不论什么理论知识,而仅仅是探讨了工作线程怎样将数据的处理结果显示到窗体这个问题,因此又一次改动标题. 另外,关于窗体和线程的相关理论知识.感觉一两句话确实说不清楚,并且<Windows 核心编程>这本书上介绍的也挺好的.有机会再写吧.特别是感觉如今好多人都直接在学 MFC,用 MFC.甚至连窗体过程,消息循环都不太明确,假设能有这样一篇博客也是非常有价值的. 为什么要讨论这个问题

mfc小工具开发之定时闹钟之---多线程急线程同步

一.MFC对多线程编程的支持 MFC中有两类线程,分别称之为工作者线程和用户界面线程.二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环. 工作者线程没有消息机制,通常用来执行后台计算和维护任务,如冗长的计算过程,打印机的后台打印等.用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等.但对于Win32的API编程而言,这两种线程是没有区别的,它们都只需线程的启动地址即可启动线程来执行任务. 在MFC中,一般用全局函数Afx