深入理解Node.js中的事件循环(带例子和分析)

本文受:

(上)https://zhuanlan.zhihu.com/p/26229293

(下)https://zhuanlan.zhihu.com/p/26238030

这两篇知乎博文的启发,对事件循环机制进行分析与总结。

 

对于JavaScript中的单线程,拥有唯一的一个事件循环,事件循环就像是一个

while (true) {
    // 执行一些代码...
}

一样,不断地去执行函数调用栈中的代码。在JavaScript代码执行时,除了依靠函数调用栈来搞定函数的执行顺序外,还要依靠任务队列来搞定另外一些代码的执行,但最终,任务队列中的代码总是会放到调用栈中去执行。

 

下面说一下事件循环机制中的几个重要的内容:

  1. 一个线程中,事件循环是唯一的,但是任务队列可以拥有多个。
  2. 任务队列又分为macro-task(宏任务)与micro-task(微任务),在最新标准中,它们被分别称为task与jobs。
  3. macro-task大概包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。
  4. micro-task大概包括: process.nextTick, Promise, Object.observe(已废弃), MutationObserver(html5新特性)。
  5. setTimeout/Promise等我们称之为任务源。而进入任务队列的是他们指定的具体执行任务。
  6. 来自不同任务源的任务会进入到不同的任务队列。其中setTimeout与setInterval是同源的。
  7. 事件循环的顺序,决定了JavaScript代码的执行顺序。它从script(整体代码)开始第一次循环。之后全局上下文进入函数调用栈。直到调用栈清空(只剩全局),然后执行所有的micro-task。当所有可执行的micro-task执行完毕之后。循环再次从macro-task开始,找到其中一个任务队列执行完毕,然后再执行所有的micro-task,这样一直循环下去。
  8. 其中每一个任务的执行,无论是macro-task还是micro-task,都是借助函数调用栈来完成。

首先,我们通过一个稍微简单一点的例子去分析,后面熟悉了之后再上一个稍微复杂一点的例子。

// 为了方便理解,我以打印出来的字符作为当前的任务名称
setTimeout(function() {
    console.log('timeout1');
})

new Promise(function(resolve) {
    console.log('promise1');
    for(var i = 0; i < 1000; i++) {
        i == 99 && resolve();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值