介绍

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

  • 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. 测试Javacript里的checkbox是否被选中的status和checked的替换方法

    测试Javacript里的checkbox是否被选中的status和checked的替换方法,checkbox.checked和checkbox.status的功能一样,注意checkbox.stat ...

  2. 一个人独立开发 3D 游戏引擎可能吗?

    作者:孙志超链接:https://www.zhihu.com/question/24733255/answer/42000966来源:知乎著作权归作者所有,转载请联系作者获得授权. 当然可以,但难道有 ...

  3. json&pickle&xml

    json .dumps()    变成 json 的字符串 import json dic={"name":"alex"} data=json.dumps(di ...

  4. Hololens开发笔记之Gesture手势识别(Manipulation手势控制物体平移)

    Manipulation gesture:保持点击手势,在3D世界中绝对运动 当你想要全息图像1:1响应用户手部移动时,操纵手势能被用于移动.缩放或旋转全息图像.如此的一个用处是使得用户可以在世界中绘 ...

  5. Linux中执行shell脚本的4种方法总结

    bash shell 脚本的方法有多种,现在作个小结.假设我们编写好的shell脚本的文件名为hello.sh,文件位置在/data/shell目录中并已有执行权限. 方法一:切换到shell脚本所在 ...

  6. [手机取证] “神器”IP-BOX的一些问题

    网上最近传的纷纷扬扬的iOS密码破解神器IP-BOX,很多人感兴趣,作为一个该产品的老用户,来破除一下迷信,顺便做个普及~ Q1:这东西好神奇,是不是所有都能破解? A1:支持简单密码的穷举,有条件的 ...

  7. 开源免费的天气预报接口API以及全国所有地区代码(国家气象局提供)

    天气预报一直是各大网站的一个基本功能,最近小编也想在网站上弄一个,得瑟一下,在网络搜索了很久,终于找到了开源免费的天气预报接口API以及全国所有地区代码(国家气象局提供),具体如下: 国家气象局提供的 ...

  8. Android学习起步 - 新建工程及相关

    新手起步迷迷糊糊,以下记录迷惑之处,大家共勉!!! 1.创建安卓应用工程 选择Andriod Application Project 点下一步直到完成. 二.下面是新建工程注意的地方 (1)首选删除系 ...

  9. Java值传递以及引用的传递、数组的传递!!

    转(http://blog.csdn.net/niuniu20008/article/details/2953785) 许多编程语言都有2种方法将参数传递给方法------按值传递和按引用传递. 与其 ...

  10. c++学习一:指针基础

    1.指针优势,当数据量比较大时,通过指针直接访问数据量所在内存.处理更 加复杂的数据结构.例如:链表.二叉树.图等.2.指针本质是一种表示内存地址的数据类型,它和整型int和浮点数float一样 只是 ...