Javascript的单线程与多线程

article/2025/10/9 10:48:22

目录

 

一、浏览器的线程和进程

1.浏览器的线程

2.浏览器是多进程的

二、Javascript是单线程的

1.异步Ajax也是单线程的

2.setInterval和setTimeout本质上并不是多线程

三、Web Worker支持多线程

1.多线程间数据交互

2.Web Worker的兼容性

3.Web Worker的使用限制

3.1同源限制

3.2访问限制

4.Web Worker的应用场景

总结


 

一、浏览器的线程和进程

1.浏览器的线程

一个浏览器通常由以下几个线程:

 

  • 渲染引擎线程:负责页面的渲染
  • JS引擎线程:负责JS的解析和执行
  • 定时触发器线程:处理定时事件,比如setTimeout,setInterval
  • 事件触发线程:处理DOM事件
  • 异步http请求线程:处理http请求

浏览器中有三个常驻的线程,分别是JS引擎线程、界面渲染线程、事件触发线程。

需要注意的是,渲染线程和JS引擎线程是不能同时进行的。渲染线程在执行任务的时候,JS引擎线程会被挂起。因为JS可以操作DOM,若在渲染中JS处理了DOM,浏览器可能就混乱了。

2.浏览器是多进程的

Google或IE浏览器每打开一个tab标签页就会有一个子进程,具体可打开任务管理器查看。

 

二、Javascript是单线程的

浏览器端JavaScript是以单线程的方式执行的,也就是说JavaScript和UI渲染占用同一个主线程,那就意味着,如果JavaScript进行高负载的数据处理,UI渲染就很有可能被阻断,浏览器就会出现卡顿,降低了用户体验。

1.异步Ajax也是单线程的

Ajax是单线程的,因为JavaScript是单线程的,Ajax属于JavaScript范畴,因此Ajax是单线程的。

Ajax请求确实是异步的,JS引擎执行异步代码而不用等待,是因为有消息队列事件循环,这请求是由浏览器新开一个线程请求。浏览器中很多行为是异步的,当一个异步事件发生的时候,它就进入事件队列,浏览器有一个内部的消息循环,Event Loop(事件循环),会轮询大的事件队列并处理事件,只有前面的处理完毕了,空闲了才会执行这个事件,而JavaScript引擎始终是单线程运行回调函数。

2.setInterval和setTimeout本质上并不是多线程

1.setTimeout,setInterval并不是多线程,只是一个定时的事件触发器,它们在合适的时间把一些JS代码塞到JS引擎的队列中。

2.setTimeout(aFunction, 0),这行代码看似的意思是在0秒之后执行aFunction, 但这并不意味着立即执行。其它真正的意思是立刻把aFunction的代码放到当前JS引擎的队列中。所以当前代码块执行完成之前,aFunction的代码是得不到执行的。

3.在一个事件的响应代码执行完成之后,即使队列中有待执行的代码,浏览器也会先执行页面渲染和响应事件,完成之后再执行队列中的代码。

 

三、Web Worker支持多线程

web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 在后台运行。

1.多线程间数据交互

Web Worker线程和原本的JS线程互不影响.

两个线程之间是通过onPostMessage 和 onMessage这两个函数来进行通讯的。其中onPostMessage(data)的参数是你要传递的数据,而onMessage是一个回调函数,只有在接受到数据时,onMessage会被回调,onMessage有一个隐藏的参数,那就是event,我们可以用event.data获取到传递过来的数据来更新主线程。

2.Web Worker的兼容性

3.Web Worker的使用限制

3.1同源限制

分配给Worker 线程运行的脚本文件(worker.js),必须与主线程的脚本文件(main.js)同源。

3.2访问限制

Worker子线程所在的全局对象,与主线程不在同一个上下文环境,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象,global对象的指向有变更,window需要改写成self,不能执行alert()方法和confirm()等方法,只能读取部分navigator对象内的数据。另外chrome的console.log()倒是可以使用,也支持debugger断点,增加调试的便利性。

4.Web Worker的应用场景

1、使用专用线程进行数学运算
Web Worke设计的初衷就是用来做计算耗时任务,大数据的处理,而这种计算放在worker中并不会中断前台用户的操作,避免代码卡顿带来不必要的用户体验。例如处理ajax返回的大批量数据,读取用户上传文件,计算MD5,更改canvas的位图的过滤,分析视频和声频文件等。worker中除了缺失了DOM和BOM操作能力以外,还是拥有非常强大的js逻辑运算处理的能力的,相当于nodejs一个级别的的运行环境。

2、高频的用户交互
高频的用户交互适用于根据用户的输入习惯、历史记录以及缓存等信息来协助用户完成输入的纠错、校正功能等类似场景,用户频繁输入的响应处理同样可以考虑放在web worker中执行。例如,我们可以 做一个像Word一样的应用:当用户打字时后台在词典中进行查找,帮助用户自动纠错等等。

3、数据的预取
对于一些有大量数据的前后台交互产品,可以新开一个线程专门用来进行数据的预取和缓冲数据,本地web数据库的行写入和更改,长时间持续的运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断,也有利于随时响应主线程的通信。也可以配合XMLHttpRequest和websocket进行不断开的通信,实现守卫进程。

最后,web worker有了多线程的形(有了多线程的用法),但还不具备多线程的神(不具备线程通信、锁等后台线程的基本特性),web worker的本质是支持我们把数据刷新与页面渲染两个动作拆开执行(不使用web worker的话这两个动作在主线程中是线性执行的)。


总结

1.Javascript是单线程的。

2.JS的异步Ajax和setInterval/setTimeout函数本质上也是单线程的。

3.Web Worker才是真正的多线程。但是使用上会有一些限制,如无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。


http://chatgpt.dhexx.cn/article/UFfngOLO.shtml

相关文章

JavaScript多线程编程

浏览器端JavaScript是以单线程的方式执行的,也就是说JavaScript和UI渲染占用同一个主线程,那就意味着,如果JavaScript进行高负载的数据处理,UI渲染就很有可能被阻断,浏览器就会出现卡顿,降低了用户体验。 …

JavaScript多线程初步学习

一、多线程理解 首先,我们要理解什么是多线程,百度百科上说:多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时…

JavaScript如何实现多线程?

今天看到一道面试题,问js如何实现多线程?下面来总结一下: 因为 JS是一种单线程语言,即使是一些异步的事件也是在JS的主线程上运行的。像setTimeout、ajax的异步请求,或者是dom元素的一些事件,都是在JS主线程执行的&a…

JS多线程

JS是多线程的吗? 多线程编程相信大家都很熟悉,比如在界面开发中,如果一个事件的响应需要较长时间,那么一般做法就是把事件处理程序写在另外一个线程中,在处理过程中,在界面上面显示类似进度条的元素。这样…

at24c16如何划分出多个读写区_mega32数组、内存以及AT24C16读写相关

主控:mega32 编译器:iar2.31E 这两天折腾一个模块程序,一个温度补偿参数,本来是72个字节,现在扩展了三倍,变成288个,然后各种问题出现了。 第一次修改时想当然,直接把两个用到的全局…

STC8H开发(十二): I2C驱动AT24C08,AT24C32系列EEPROM存储

目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解)STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解)STC8H开发(三): 基于FwLib_STC8的模数转换ADC介绍和演示用例说明STC8H开发(四): FwLib_STC8 封装库的介绍和使用注意事项STC8H开发(五…

STM32的硬件I2C与AT24C16

刚学STM32的时候就听闻STM32的硬件I2C存在重大bug,会导致运行卡死在等待ACK的过程中,所以一直以来对其避而远之,转而以模拟I2C取代之。最近这段时间一直在用STM32 CubeMX,图形化设置界面屡试不爽,连USB这种复杂外设都能…

STM32F030 硬件I2C驱动 AT24C16

网络上很多F1系列的ATC24的读写程序,但F0几乎没有。由于F0完全重写了I2C,所以以往的代码并不能直接使用,修改事件、接口上会浪费很多时间,特别是对于使用F0系列进行入门的新手。 在此十分感谢 畅学电子网 的对于AT24C16的资料&am…

EEPROM 之 AT24C16 - 备忘录

因为论坛里看到STM的I2C有点小bug,所以这里采用的是模拟I2C时序 【注】m0.6us表示的是这一段时间最小不能小于为0.6us,M0.6us表示的是这一段时间最大为0.6us 对AT24C16的操作有读和写,读又分为CURRENT ADDRESS READ、RANDOM READ、SEQUENTIAL…

S32K144:12.LPI2C驱动AT24C16

1.打开官方例程 2.修改引脚配置 3.时钟可按照实际情况修改,也可不用更改,本例时钟不做更改 4.配置LPI2C模块 设置从机地址:从机地址如下图所示,低三位表示为AT24C16的块地址,AT24C16将2KB的内存空间分为8个块&…

stm32cubemx I2C读取AT24C16

本文对如何使用stm32cube生成I2C工程不作说明,仅对在对AT24Cxx系列的使用时作出易忽略的说明; 1、at24cxx页面结构: 从该图可以看出16K(bit)共有128个页,每页由16byte构成。16k 128 * 16 * 8; 特别注意&…

STM32之 AT24C16(EEPROM)驱动代码(程序稳定,清晰明了)

AT24C16电路图 第一部分:IIC协议代码头文件(iic.h) #ifndef IIC_H #define IIC_H #include "stm32f10x.h" #include "sys.h" #include "delay.h"#define write 0 #define read 1//IIC总线地址接口定义 #define IIC_SCL PBout(7) #d…

GD32F4xx MCU控制I2C EEPROM(AT24C16)记录

1、AT24C16简介 1.1 主要参数 工作电压:1.8v ~ 5.5v存储空间:2048 Bytes ,分128页,16Bytes/页, 地址范围 0~2047。接口: I2C 总线I2C时钟频率: 1MHz( 5v ) , 400KHz( 1.8v, 2.5v, 2.7v)。1.2 电路连接 1.3 其他说明 AT24C16未使用器件地址引脚,总线上最多只可以连接一…

AT24C04、AT24C08、AT24C16系列EEPROM芯片单片机读写驱动程序

一、概述 在之前的一篇博文中,记录了AT24C01、AT24C02芯片的读写驱动,先将之前的相关文章include一下: 1.IIC驱动:4位数码管显示模块TM1637芯片C语言驱动程序 2.AT24C01/AT24C02读写:AT24C01/AT24C02系列EEPROM芯片单…

IIC方式读驱动AT24C16芯片

闲来无事,找了块msp430的板子编写了个IIC驱动AT24C16的程序。 IIC作是一种简单,双向,同步的二进制总线,由SDA数据线和SCL时钟线组成,所有接到IIC总线上的各设备的SDA数据线都连接到总线的SDA数据线上,用来…

AT24C16页写和多页写

AT24C16 2K字节(存储内存) 128(页面数)* 16 (每页的字节数) 2^11 (寻址地址位数 11位)。 AT24C16有128(2^7128)页只需要7位地址,分为高3位和低4位,高3位在设备地址中,低4位在字地址中。 设备…

EEPROM(AT24C16)页写算法

1. 写在前面 学习单片机或者从事嵌入式开发的,对于EEPROM绝不会陌生,尤其的24系列的EEPROM很是经典,或者与此兼容的FRAM系列,如AT24C02、AT24C16、FM24C16等。 驱动起这个系列的EEPROM,可以说是没有任何难点&#xff0…

AT24C16 读写注意点

开篇一张时序图镇楼: 这篇文章介绍了AT24C16的页写、连续读、写保护功能:AT24C16 读写_D.luffy的博客-CSDN博客_at24c16 页写算法我是参考这篇文章的:https://acuity.blog.csdn.net/article/details/78550427?utm_ char ee_24clxx_writeby…

AT24C16 读写

at24c16 有8块 256字节组成,共2K字节16K bit I2C开始信号后,第一个字节为器件地址,由10103位块地址1位读写标志组成, 3位块地址刚好可以表示 8个块, 所以一次写完256字节,换到下一下块的时候,要…

进程间通信的方式(附代码分析)

进程间通信的方式 1. 进程间通信的几种方式 管道 比如 ls | grep 1;也就是将 进程 ls 拿到的结果作为 grep 1 这个进程的输入。实现了进程间的通信。 消息队列 消息队列就是我们的内核给我们创建的一种消息队列。我们可以往其中发送消息,也可以从其中接收消息。 …