介绍

在读这篇博客之前,我强列建议先阅读我的前两篇文章:

  • Getting Started With Node.js

  • Node.js - Modules

    在这篇文章中,我们将学习 Node.js 中的事件循环(event loop)。我们还将了解 Node.js 的代码执行过程。在我第一篇文章中我告诉大家 Node.js 是一个单线程的应用程序。因为 Node.js 运行的是 JavaScript,然而 JavaScript 是不支持多线程的,所以 Node.js 也不支持多线程。但是 Node.js 使用事件和回调(event and callbacks)的概念可以支持并发。这一切归咎都是事件循环(event loop)的功劳。

事件循环(event loop)的工作机制

Getting Started With Node.js 这篇文章中我们已经了解了 Node.js 的架构,其中我们还讨论了 Node.js 的两个主要组件:Google's V8 引擎 和 Libuv。其中事件循环(event loop)是用 C 和 C++ 编写的 Libuv 的一部分。



上图是 Node.js 的执行过程,让我们来一步一步理解它。

  1. 每当请求进入 Node.js 的 API 时将会被添加到事件循环(event loop)的队列,因为 Node.js 不能同时处理多个请求。所以,所有的请求进来后将会被添加到事件队列里面。
  2. 现在,你可以在上图中看到一个循环,它总是检查事件或请求是否在事件队列中可用。如果有任何请求可用,那么根据队列的“先进先出”的特性,该请求将会被处理。
  3. Node.js 的事件循环(event loop)是单线程执行的非阻塞 I/O 任务。它将请求发送到 C++ 内部线程池(thread pool),里面可以运行大量的线程任务。这个内部 C++ 线程池(thread pool)是 Libev 组件中开发的事件循环(event loop)的一部分,它可以处理多个请求。事件循环一直检查事件队列中是否存在任务,如果有并且阻塞进程存在,将会有线程池来处理。
  4. 现在,内部线程池(thread pool)可以处理很多请求,就像对数据库请求,对文件的操作等等。
  5. 每当有线程完成任务,将会调用回调函数(callback function),并将响应结果发送回事件循环(event loop)。
  6. 事件循环将响应发送回请求客户端完成一次请求处理。

示例

下面的示例将会展示事件循环(event loop)的工作机制:

var fs = require('fs');
var i = 1;
fs.watch("file.txt", function (event, filename) {
var EventId = "#" + i;
var EventName = " Event: " + event;
var FileName = " FileName: " + filename;
var Time = " Time: " + new Date();
var data = EventId.concat(EventName, FileName, Time, "\n");
console.log(data);
i++;
});
console.log("Now we are watching file.txt\n");

在上面的示例中,第一行加载了 fs 模块用于操作文件系统,并且定义了一个变量 i 来做为计数器。然后使用 fs.watch() 方法来监视 file.txt 文件。这个监视方法的回调函数的参数包含了事件(event)和文件名(filename)。所以,每当文件有变化,这个回调函数将会被调用,并将日志打印到控制台上面。我们将上面的代码保存为 app.js

注:我的 file.txt 文件和 app.js 在同一个目录,我的文件结构如下图如示:



现在,我们运行程序,并修改这个 file.txt 文件。当我们保存后,将会看到下面的输出日志:



上面的结果显示,当 file.txt 发生任何变化,fs.watch() 的回调函数将会在事件循环(event loop)中被调用,并且事件循环(event loop)将会一直检查文件是否发生了变化。你还可以使用下面的代码将该事件信息记录在一个文件中:

var fs = require('fs');
fs.writeFile('log.txt', '', function (err) {
if (err) throw err;
console.log('File Saved Successfully!');
});
var i = 0;
fs.watch("target.txt", function (event, filename) {
var EventId = "#" + i;
var EventName = " Event: " + event;
var FileName = " FileName: " + filename;
var Time = " Time: " + new Date();
var data = EventId.concat(EventName, FileName, Time,"\n");
fs.appendFile('log.txt', data, function (err) {
if (err) {
console.log(err);
}
});
i++;
});

好了,我希望这篇文章对你有帮助。谢谢!

译:http://www.c-sharpcorner.com/article/node-js-event-loop/

[译]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. JS event loop

    一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Java ...

  6. (译)Node.js的 EventEmitter 教程

    原文标题:Node.js EventEmitter Tutorial 原文链接:http://www.hacksparrow.com/node-js-eventemitter-tutorial.htm ...

  7. [译]Node.js Interview Questions and Answers (2017 Edition)

    原文 Node.js Interview Questions for 2017 什么是error-first callback? 如何避免无止境的callback? 什么是Promises? 用什么工 ...

  8. 译\Node.js应用的持续部署

    Node.js应用的持续部署 翻译前 翻译自:https://blog.risingstack.com/continuous-deployment-of-node-js-applications/ 正 ...

  9. [译]Node.js : Building RESTful APIs using Loopback and MySQL

    国庆后可能就要使用StrongLoop那套东西来做项目了 原文:http://www.javabeat.net/loopback-mysql/ Loopback是什么? Loopback是一个开源的N ...

随机推荐

  1. EXCEL日期间隔函数

    =DATEDIF(D3,TODAY(),"M") 日期一列有逗点,有横线,excel建议日期用横杠. 首先将日期列选择日期格式. 其次通过查找替换,将.换为- 之后用=DATEDI ...

  2. RT-Thread下的串口驱动程序分析【转载】

    编写本文稿的目的,在于通过分析stm32平台上的串口中断源码,学习 RTT中如何编写中断处理程序 如何编写RTT设备驱动接口代码 了解串行设备的常见处理机制 先以RTT官方源码中的STM32 BSP包 ...

  3. DNS错误 事件4000 4013

    DNS 错误事件4000 4013,无法创建活动目录本身的区域 WINDOWS 2003 DNS服务器无法解析 错误ID 4000 DNS 服务器无法打开 Active Directory.这台 DN ...

  4. bootstrapvalidator校验、校验清除重置

    //保存 function saveAdmin(){ //开启验证 $('#saveadmin_form').data('bootstrapValidator').validate(); if(!$( ...

  5. jQuery中attr()、prop()、data()用法及区别

    .attr(),此方法从jq1.0开始一直存在,官方文档写的作用是读/写DOM的attribute值,其实1.6之前有时候是attribute,有时候又是property..prop(),此方法jq1 ...

  6. EventBus--介绍

    注意: 1,post()方法里面的类型和onEvent()中的类型要一致., 2,订阅者对象中 必须有 onEvent 的 public 方法     ---public void onEvent(O ...

  7. (Collection)350. Intersection of Two Arrays II

    /* Given two arrays, write a function to compute their intersection. Example: Given nums1 = [1, 2, 2 ...

  8. 通过创建临时表合并hive小文件

    #!/bin/bash #set -x DB=$1 #获取hive表定义 ret=$(hive -e "use ${DB};show tables;"|grep -v _es|gr ...

  9. Android 进程通信机制之 AIDL

    什么是 AIDL AIDL 全称 Android Interface Definition Language,即 安卓接口描述语言.听起来很深奥,其实它的本质就是生成进程间通信接口的辅助工具.它的存在 ...

  10. insertAdjacentHTML方法示例

    添加HTML内容与文本内容以前用的是innerHTML与innerText方法,最近发现还有insertAdjacentHTML和insertAdjacentText方法,这两个方法更灵活,可以在指定 ...