带你了解NodeJS事件循环

 更新时间:2022年02月14日 10:27:45   作者:隐冬  
这篇文章主要介绍NodeJS事件循环,Node中代码从上到下同步执行,在执行过程中会将不同的任务添加到相应的队列中,那具体有的循环又是怎么回事呢,限免现编就带大家学习该详细内容,需要的朋友也可以参考一下

浏览器中存在两个任务队列,一个是宏任务一个是微任务。但是在NodeJS中一共存在六个事件队列,timerspending callbacks,idle preparepoll,checkclose callbacks。每一个队列里面存放的都是回调函数callback

这六个队列是按顺序执行的。每个队列负责存储不同的任务。

  • timer里面存在的是setTimeout与setInterval的回调函数
  • pending callback是执行操作系统的回调,例如tcp,udp。
  • idle prepare只在系统内部进行使用。一般开发者用不到
  • poll执行与IO相关的回调操作
  • check中存放setImmediate中的回调。
  • close callbacks执行close事件的回调。

在Node中代码从上到下同步执行,在执行过程中会将不同的任务添加到相应的队列中,比如说setTimeout就会放在timers中, 如果遇到文件读写就放在poll里面,等到整个同步代码执行完毕之后就会去执行满足条件的微任务。可以假想有一个队列用于存放微任务,这个队列和前面的六种没有任何关系。

当同步代码执行完成之后会去执行满足条件的微任务,一旦所有的微任务执行完毕就会按照上面列出的顺序去执行队列当中满足条件的宏任务。

首先会执行timers当中满足条件的宏任务,当他将timers中满足的任务执行完成之后就会去执行队列的切换,在切换之前会先去清空微任务列表中的微任务。

所以微任务执行是有两个时机的,第一个时机是所有的同步代码执行完毕,第二个时机队列切换前。

注意在微任务中nextTick的执行优先级要高于Promise,这个只能死记了。

setTimeout(() => {
    console.log('s1');
})

Promise.resolve().then(() => {
    console.log('p1');
})

console.log('start');

process.nextTick(() => {
    console.log('tick');
})

setImmediate(() => {
    console.log('st');
})

console.log('end');

// start end tick p1 s1 st
setTimeout(() => {
    console.log('s1');
    Promise.resolve().then(() => {
        console.log('p1');
    })
    process.nextTick(() => {
        console.log('t1');
    })
})

Promise.resolve().then(() => {
    console.log('p2')
})

console.log('start');

setTimeout(() => {
    console.log('s2');
    Promise.resolve().then(() => {
        console.log('p3');
    })
    process.nextTick(() => {
        console.log('t2');
    })
})

console.log('end');

// start end p2 s1 s2 t1 t2 p1 p3

Node与浏览器事件环执行是有一些不同的。

首先任务队列数不同,浏览器一般只有宏任务和微任务两个队列,而Node中除了微任务队列外还有6个事件队列。

其次微任务执行时机不同,不过他们也有相同的地方就是在同步任务执行完毕之后都会去看一下微任务是否存在可执行的。对浏览器来说每当一个宏任务执行完成之后就会清空一次微任务队列。在Node中只有在事件队列切换时才会去清空微任务队列。

最后在Node平台下微任务执行是有优先级的,nextTick优先于Promise.then, 而浏览器中则是先进先出。

setTimeout(() => {
    console.log('timeout');
})

setImmediate(() => {
    console.log('immdieate');
})

在Node中时而会先输出timeout时而会先输出immdieate,这是因为setTimeout是需要接收一个时间参数的,如果没写就是一个0,我们都知道无论是在Node还是在浏览器,程序是不可能真的是0,他会受很多的因素影响。这取决于运行的环境。

如果setTimeout先执行就会放在timers队列中,这样timeout就会先输入,如果setTimeout因为某些原因后执行了,那么check队列中的immdieate就会先执行。这就是为什么时而输出timeout时而输出immdieate

const fs = require('fs');

fs.readFile('./a.txt', () => {
    setTimeout(() => {
        console.log('timeout');
    }, 0)

    setImmediate(() => {
        console.log('immdieate');
    })
})

这种情况就会一直先输出immdieate后输出timeout,这是因为,代码执行的时候会在timers里面加入timeout, 在poll中加入fs的回调,在check中加入immdieate。fs的回调执行结束之后实在poll队列,队列切换的时候首先会去看微任务,但是这里没有微任务就会继续向下,下面就是check队列而不是timers队列,所以poll清空之后会切换到check队列,执行immdieate回调。

到此这篇关于带你了解NodeJS事件循环的文章就介绍到这了,更多相关NodeJS事件循环内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于在mongoose中填充外键的方法详解

    关于在mongoose中填充外键的方法详解

    在学习非关系型数据库mongoDB,希望能够完成数据库的CRUD,采用的是JS做的后台,因此用到了mongoose,下面这篇文章主要给大家介绍了关于在mongoose中填充外键的相关资料,文中介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-08-08
  • Windows系统下安装Node.js的步骤图文详解

    Windows系统下安装Node.js的步骤图文详解

    这篇文章主要给大家介绍了Windows系统下Node.js的安装教程,Node.js是用于后端编程的JavaScript框架,文中给出了详细图文介绍,有需要的朋友可以参考下,下面来一起看看吧。
    2016-11-11
  • node.js突破nginx防盗链机制,下载图片案例分析

    node.js突破nginx防盗链机制,下载图片案例分析

    这篇文章主要介绍了node.js突破nginx防盗链机制,下载图片的方法,结合具体案例形式分析了防盗链的相关原理与node.js使用axios库下载防盗链图片的相关操作技巧,需要的朋友可以参考下
    2023-04-04
  • 使用 Node.js 对文本内容分词和关键词抽取

    使用 Node.js 对文本内容分词和关键词抽取

    这篇文章主要介绍了使用 Node.js 对文本内容分词和关键词抽取,需要的朋友可以参考下
    2017-05-05
  • 支持cjs及esm的npm包实现示例详解

    支持cjs及esm的npm包实现示例详解

    这篇文章主要为大家介绍了支持cjs及esm的npm包的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Node.js学习教程之Module模块

    Node.js学习教程之Module模块

    这篇文章主要给大家介绍了关于Node.js学习教程之Module模块的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Node.js具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • Nodejs实现爬虫抓取数据实例解析

    Nodejs实现爬虫抓取数据实例解析

    这篇文章主要介绍了Nodejs实现爬虫抓取数据实例解析,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友参考下吧
    2018-07-07
  • Node使用Nodemailer发送邮件的方法实现

    Node使用Nodemailer发送邮件的方法实现

    这篇文章主要介绍了Node使用Nodemailer发送邮件的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环

    我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环

    本篇文章主要介绍了node.js的几个重要的知识点:node.js作用、回调、同步和异步代码 以及事件循环
    2014-07-07
  • Node.js API详解之 timer模块用法实例分析

    Node.js API详解之 timer模块用法实例分析

    这篇文章主要介绍了Node.js API详解之 timer模块用法,结合实例形式分析了Node.js API中timer模块基本功能、原理、用法及操作注意事项,需要的朋友可以参考下
    2020-05-05

最新评论