本文基于node 0.10.22版本

关于EventLoop是什么,请看阮老师写的什么是EventLoop

本文讲述的是EventLoop中的执行顺序(着重讲setImmediate, setTimeout/setInterval, I/O的顺序)

首先看看github上看到的nodejs eventloop 的图解, 来源于https://github.com/joyent/node/issues/6034#issuecomment-30017889

(注意图中timers处process.nextTick仍可以优先于timers处执行,可能是图中有遗漏, 任何回调中设置的nextTick都会在回调结束时最优先调用,所有nextTick执行完毕才会继续EventLoop的遍历)

解释一下:

每一次EventLoop会按以下顺序遍历 timers ->poll(I/O)->check(immediates)

  • timers阶段会将达到延时的回调依次执行完,该阶段中设置的timers都不会在该次event loop中执行,即使已到达延时
  • poll阶段会将已返回数据的I/O回调依次执行完毕,该阶段设置的I/O都不会在该次event loop中执行,即使数据已经返回
  • check阶段将只执行一个最先设置的immediate回调,就跳出该阶段了
  • timers阶段若设置了I/O任务,并且在poll阶段前数据就已经返回,该I/O回调将会在该次event loop的poll阶段执行
  • timers和poll阶段若设置了immediates的回调,并且此回调是最先设置的回调,则该回调会在该次event loop的check阶段执行
setTimeout(function(){
//第一次进入event loop
console.log('setTimeout - 1');
//timers中设置的timers只会在下次event loop中执行
setTimeout(function(){
console.log('setTimeout - 2');
}, 0)
//timers中设置的io延时足够低时将在这次event loop中执行
fs.stat('file', function(){
console.log('I/O');
}) ;
//timers或poll阶段设置的immediate回调若是该immediates回调数组中的第一个,将在这次Event loop中执行
setImmediate(function(){
console.log('setImmediate');
}) ;
}, 0);

注意: 一个eventloop的时间并不确定,我们不能确定程序处于哪个阶段处于哪个eventloop,能确定的只有[同一个eventloop内的执行顺序]

送上负责nodejs的event loop部分(c++)的libuv库的介绍:http://nikhilm.github.io/uvbook/index.html

补充一下:(个人理解)

idle阶段指的是进程属于闲置状态,没有更多的事件需要处理

prepare阶段指的是进程开始阻塞(也就是同步代码开始运行)前的阶段

(刚接触nodejs,还没了解到有哪些借口可以为这两个阶段设置回调)

check阶段指的是进程阻塞完毕后的阶段

【Node.js】Event Loop执行顺序详解的更多相关文章

  1. Node.js Event Loop 的理解 Timers,process.nextTick()

    写这篇文章的目的是将自己对该文章的理解做一个记录,官方文档链接The Node.js Event Loop, Timers, and process.nextTick() 文章内容可能有错误理解的地方 ...

  2. The Node.js Event Loop, Timers, and process.nextTick() Node.js事件循环,定时器和process.nextTick()

    个人翻译 原文:https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ The Node.js Event Loop, Ti ...

  3. Node.js event loop 和 JS 浏览器环境下的事件循环的区别

    Node.js  event loop 和 JS 浏览器环境下的事件循环的区别: 1.线程与进程: JS 是单线程执行的,指的是一个进程里只有一个主线程,那到底什么是线程?什么是进程? 进程是 CPU ...

  4. The Node.js Event Loop, Timers, and process.nextTick()

    The Node.js Event Loop, Timers, and process.nextTick() | Node.js https://nodejs.org/uk/docs/guides/e ...

  5. [译]Node.js - Event Loop

    介绍 在读这篇博客之前,我强列建议先阅读我的前两篇文章: Getting Started With Node.js Node.js - Modules 在这篇文章中,我们将学习 Node.js 中的事 ...

  6. Unity 继承MonoBehaviour脚本 执行顺序 详解

    先看结果 Awake ->OnEnable-> Start ->-> FixedUpdate-> Update  -> LateUpdate ->OnGUI ...

  7. JS中的async/await的执行顺序详解

    虽然大家知道async/await,但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 JavaScript 的 async/await(如果对async/await不熟悉 ...

  8. javascript运行机制之执行顺序详解(转)

    转自http://www.admin10000.com/document/3385.html JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言, ...

  9. javascript 执行顺序详解

    JavaScript是一种描述 型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行.如果你不能理解javaScript 语言的运行机制,或者简 ...

随机推荐

  1. 基于.NET MVC的高性能IOC插件化架构(一)

    最近闲下来,整理了下最近写的代码,先写写架构,后面再分享几个我自己写的插件 最近经过反复对比,IOC框架选择了Autofac,原因很简单,性能出众,这篇博文是我的各大IOC框架的性能测试:http:/ ...

  2. UI、ID、UE和GUI,这些都是什么

    在网页和应用设计领域中,我们经常会听到人们用这些英文缩写描述设计工作,那么它们各自代表什么含义?具体的工作.方向和区别是什么呢? 下面让我们先来看看它们的英文全称和基本概念. UI(User Inte ...

  3. VS2010安装项目的系统必备中添加.NET 2.0

    把DotNetFX.rar解压后的DotNetFX文件夹,放置于安装了 VS2010 的 C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bootstrap ...

  4. data-theme 几种值的样式

    代码片段: <div data-role="page"> <div data-role="header"> <h1>The ...

  5. Web.Config 对静态文件 js css img 的客户端缓存策略

    <?xml version="1.0" encoding="utf-8"?> <configuration> <system.we ...

  6. 转: Python 运算符与用法

    +加两个对象相加 3 + 5得到8.'a' + 'b'得到'ab'. (注意:6+'a'这样是错误的,但在PHP里这样是可以运行的) -减得到负数或是一个数减去另一个数 -5.2得到一个负数.50 - ...

  7. 【转】Beagleboard:BeagleBoneBlack

    原文网址:http://elinux.org/Beagleboard:BeagleBoneBlack Did you know that elinux.org has Mailing Lists? P ...

  8. leetcode-Consecutive numbers

    Write a SQL query to find all numbers that appear at least three times consecutively. +----+-----+ | ...

  9. Linux下创建、查看、提取和修改静态库(*.a)

    先说明一点,静态库文件是由多个目标文件打包而成的,在windows下静态库文件的后缀是.lib,而在linux下静态库文件的后缀是.a(a是archive的缩写,也就是文档文件). 废话少说,下面直接 ...

  10. spring aop实现原理

    通过两种代理方式,一是JDK本身的代理方式,二是CGLIB提供的代理方式,在代理类的前面加事务begin,在后面加事务commit,需要的数据库连接从ThreadLocal中取