Nodejs 必知的「事件循环」

简介: JavaScript引擎本身不实现事件循环机制。浏览器中的事件循环由浏览器实现的,NodeJS中事件循环主要是由底层Libuv库实现的。Libuv库是事件驱动的,其封装和统一了不同平台的API实现。NodeJS的跨平台和事件循环机制都是通过Libuv库实现的。

三言两语

这是我第三次学习事件循环,这次学明白啦。吃透NodeJS相关的原理,提高自己的水平。

今天沉淀总结下学习到内容

事件循环模型

JavaScript引擎本身不实现事件循环机制。浏览器中的事件循环由浏览器实现的,NodeJS中事件循环主要是由底层Libuv库实现的。

Libuv库是事件驱动的,其封装和统一了不同平台的API实现。NodeJS的跨平台和事件循环机制都是通过Libuv库实现的。

node事件循环.png

以上分四个步骤:

1、NodeJS的V8引擎解析JavaScript代码,然后调用Node API

2、NodeAPI将任务分配给Libuv库处理,

3、Libuv中通过事件循环机制管理这些任务的执行,处理结束后将结果返回给V8引擎。

4、V8引擎回调处理Libuv返回

微任务与宏任务

根据任务种类,划分不同的任务队列,微任务队列和宏任务队列。

宏任务:setTimeout、setInterval、setImmediate

微任务:promise.then()、promise.catch()、process.nextTick()

事件循环各阶段

  • timers阶段:执行所有setTimeout和setInterval的回调
  • pendding callback阶段:某些系统操作的回调。如TCP连接的错误
  • poll阶段:轮询等待新的链接和请求等事件,执行I/O回调。比如:文件读取操作
  • check阶段:执行setImmedidate的回调
  • close callback阶段:关闭回调执行,如socket.on(close...)

每个阶段都会执行当前阶段的任务队列,然后再执行当前阶段的微任务队列,只有执行完所有微任务才进行入下一阶段。

浏览器中事件循环区别:

浏览器中没有分多个阶段;优先级别:同步代码,微任务,宏任务

浏览器中,宏任务可能会有多个队列,但是微任务只有一个,每次都会先执行完微任务再执行宏任务

陈述总结

主要学习了,NodeJS的事件循环的模型,从V8引擎解析JS代码,然后调用NodeAPI,NodeAPI将任务分配给底层Libuv库去执行,主要事件循环机制都是由Libuv库完成的。

整个事件循环划分了6个阶段:timer阶段,pendding callback阶段、poll阶段、check阶段、close callback阶段,执行的顺序是:每个阶段中的任务队列执行完后再执行微任务,只有微任务执行完成后再执行下一个阶段。浏览器的事件循环没有划分阶段,优先级顺序:同步代码、微任务、宏任务。

面试题

题1:你对NodeJS的事件循环的理解?

回答:我对事件循环的理解Node是单线程的,主线程将所有任务都放在循环队列中,然后由底层的libuv库从循环事件队列中取出任务分配给不同的线程去处理,主线程同时也会进行回调处理,整个过程形成事件循环。

与浏览器事件循环不同点:

1、浏览器没有划分多个阶段

2、浏览器任务优先级:同步代码,微任务,宏任务

题2:事件队列中的任务执行顺序?

回答:NodeJS事件循环是划分多个阶段,执行顺序是:一个阶段执行完成后,再执行微任务,然后再进行下一阶段的执行。

目录
相关文章
|
7天前
|
JavaScript
Electron——如何使用nodejs工作线程
Electron——如何使用nodejs工作线程
20 4
|
1月前
|
存储 调度 Python
异步编程概述在 Python中,`asyncio`库提供了对异步I/O、事件循环、协程(coroutine)和任务的支持。
异步编程概述在 Python中,`asyncio`库提供了对异步I/O、事件循环、协程(coroutine)和任务的支持。
|
3月前
|
前端开发 JavaScript UED
|
12月前
|
网络协议 关系型数据库 MySQL
swoole协程框架?
Swoole是一个高性能的PHP扩展,可以用于构建异步、并发和高性能的网络应用。它提供了许多底层网络通信和多进程管理的功能,使得开发者可以更轻松地编写高性能的服务器程序。
83 0
|
消息中间件 Web App开发 前端开发
事件循环总结
事件循环总结
106 0
|
前端开发 JavaScript API
关于事件循环我所知道的
关于事件循环我所知道的
76 0
|
调度 Python
Python3的原生协程(Async/Await)和Tornado异步非阻塞
我们知道在程序在执行 IO 密集型任务的时候,程序会因为等待 IO 而阻塞,而协程作为一种用户态的轻量级线程,可以帮我们解决这个问题。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存,在调度回来的时候,恢复先前保存的寄存器上下文和栈。因此协程能保留上一次调用时的状态,即所有局部状态的一个特定组合
Python3的原生协程(Async/Await)和Tornado异步非阻塞
|
Web App开发 移动开发 JavaScript
重温js—— 事件循环
大家都知道,js是单线程的语言。为啥要设置成单线程的呢? 不妨大家想一想,如果js是多线程的语言,一个线程来操作删除dom,一个线程来新增dom.那么这两个谁能先完成?结果就会变得不可控制。但是这里有的人肯定会说,html5提出了workers可以来启动多线程。没错,workers是可以用于启动多线程,在worker线程中你可以运行任何你喜欢的代码,不过有一些例外情况。比如:在worker内,不能直接操作DOM节点,也不能使用window对象的默认方法和属性,这也是存在一些弊端的(本质上也还是单线程)。
重温js—— 事件循环
|
设计模式 监控 JavaScript
Python 异步: 什么是事件循环 ?(6)
asyncio 程序的核心是事件循环。在本节中,我们将花点时间看一下 asyncio 事件循环。
168 0
|
缓存 JavaScript Unix
Nodejs多进程
nodejs学习笔记
98 0
Nodejs多进程