事件循环机制:JavaScript被设计为单线程,那如何做到异步的呢?

开发 前端
JavaScript既然被设计为单线程,是如何做到异步的呢?这时就用到了JavaScript的事件循环机制。

JavaScript是单线程的语言,单线程是指所有的程序路径按照一定的顺序执行,只有前面的程序执行了,后面的程序才会执行。

也就是说在同一时间,JavaScript只能做一件事情,为了协调浏览器产生的各种事件、网络处理、前端渲染等行为,js的事件循环机制,即EventLoop应运而生。

JavaScript是单线程的原因

js的设计初衷是作为浏览器的脚本语言,浏览器中涉及到与用户互动、频繁操作DOM等动作,如果js设计为多线程,会有很复杂的线程同步问题,即使同步问题被解决,也会降低浏览器的响应效率,得不偿失,因此,JavaScript被设计为单线程保证浏览器动作的一致性。

事件循环(EventLoop)

JavaScript既然被设计为单线程,是如何做到异步的呢?这时就用到了JavaScript的事件循环机制。

如下图所示为JavaScript事件循环的原理图。

事件循环机制:JavaScript被设计为单线程,那如何做到异步的呢?

如图所示,事件循环是主线程循环读取任务队列中的任务,直到所有的任务都被执行。在事件循环中,JavaScript用到了栈、堆以及队列等数据结构。

  • 栈中存放的是执行上下文,有函数被调用时,就会创建上下文存放在执行栈中。
  • 堆中表示一个非结构化的内存区域,用来存放对象。队列是指任务队列,用于存放异步任务。
  • js引擎遇到一个异步事件之后不会一直等待事件的返回结果,而是将事件挂起,继续执行执行栈中的其他任务。

当异步事件返回结果时,js将异步事件callback函数放入队列中,被放入队列中的异步事件不会立即回调,等到当前执行栈中的任务都执行完成,处于闲置状态的主线程按照队列顺序将处于首位事件的callback函数放入执行栈中,执行该函数的同步代码,如果遇到了异步事件,同样也会将其回调函数放入事件队列中......

如此反复,就形成了一个无限循环,这也是被称为“事件循环(EventLoop)”的原因。

宏任务(Micro task)和微任务(Macro task)

js事件循环的基本原理已经描述清楚,但是异步任务之间也有所不同。

上面讲到,JavaScript在执行异步任务时,回调函数会被放在js的任务队列中,实际上,回调函数的类别不同,执行的优先级也不同。

不同的优先级被分为两类,一类是宏任务(Micro task),一类是微任务(Macro task)。

回调函数是微任务时,会被放在微任务队列,回调函数是宏任务时,会被放在宏任务队列。微任务的优先级高于宏任务,当主线程的任务执行完成时,会首先去执行微任务队列中首位的回调函数,当微任务队列中为空时,才回去执行宏任务队列中的回调函数。

常见的微任务有:promise,常见的宏任务有setInterval等。

因此,事件循环的执行流程图如下所示:

事件循环机制:JavaScript被设计为单线程,那如何做到异步的呢?

责任编辑:赵宁宁 来源: 今日头条
相关推荐

2021-01-10 11:21:33

JavaScript语言开发

2022-05-10 08:31:44

RedisQPS单线程

2017-03-06 14:08:38

JavaScript单线程setTimeout

2024-02-26 00:00:00

JavaScript单线程高效

2016-09-06 21:23:25

JavaScriptnode异步

2021-08-16 15:49:31

开发框架单线程异步

2009-07-10 09:05:20

SwingWorker

2020-09-28 14:41:24

Event Loop

2011-06-22 09:45:46

JavaScriptAPI

2020-06-16 14:19:50

Javascript多线程编程

2021-10-15 09:56:10

JavaScript异步编程

2020-10-26 08:55:52

Redis单线程模型

2020-11-09 09:33:37

多线程

2022-01-04 11:11:32

Redis单线程Reactor

2010-08-30 08:55:56

JavaScript引

2010-01-28 16:45:44

Android单线程模

2019-12-06 10:59:20

JavaScript运行引擎

2023-10-15 12:23:10

单线程Redis

2018-05-13 21:57:04

JavaScript异步编程方案

2019-11-25 10:13:52

Redis单线程I
点赞
收藏

51CTO技术栈公众号