详解node.js 事件循环


Posted in Javascript onJuly 22, 2020

Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。

Node.js 几乎每一个 API 都是支持回调函数的。

Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现。

Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数.

事件驱动程序

Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。

当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。

这个模型非常高效可扩展性非常强,因为 webserver 一直接受请求而不等待任何读写操作。(这也称之为非阻塞式IO或者事件驱动IO)

在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。

详解node.js 事件循环

整个事件驱动的流程就是这么实现的,非常简洁。有点类似于观察者模式,事件相当于一个主题(Subject),而所有注册到这个事件上的处理函数相当于观察者(Observer)。

Node.js 有多个内置的事件,我们可以通过引入 events 模块,并通过实例化 EventEmitter 类来绑定和监听事件,如下实例:

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();

以下程序绑定事件处理程序:

// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);

我们可以通过程序触发事件:

// 触发事件
eventEmitter.emit('eventName');

实例

创建 main.js 文件,代码如下所示:

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
 
// 创建事件处理程序
var connectHandler = function connected() {
  console.log('连接成功。');
 
  // 触发 data_received 事件 
  eventEmitter.emit('data_received');
}
 
// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
 
// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
  console.log('数据接收成功。');
});
 
// 触发 connection 事件 
eventEmitter.emit('connection');
 
console.log("程序执行完毕。");

接下来让我们执行以上代码:

$ node main.js
连接成功。
数据接收成功。
程序执行完毕。

Node 应用程序是如何工作的?
在 Node 应用程序中,执行异步操作的函数将回调函数作为最后一个参数, 回调函数接收错误对象作为第一个参数。

接下来让我们来重新看下前面的实例,创建一个 input.txt ,文件内容如下:

三水点靠木 3water

创建 main.js 文件,代码如下:

var fs = require("fs");

fs.readFile('input.txt', function (err, data) {
  if (err){
   console.log(err.stack);
   return;
  }
  console.log(data.toString());
});
console.log("程序执行完毕");

以上程序中 fs.readFile() 是异步函数用于读取文件。 如果在读取文件过程中发生错误,错误 err 对象就会输出错误信息。

如果没发生错误,readFile 跳过 err 对象的输出,文件内容就通过回调函数输出。

执行以上代码,执行结果如下:

程序执行完毕
三水点靠木 3water

接下来我们删除 input.txt 文件,执行结果如下所示:

程序执行完毕
Error: ENOENT, open 'input.txt'

因为文件 input.txt 不存在,所以输出了错误信息。

以上就是详解node.js 事件循环的详细内容,更多关于node.js 事件循环的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
一段多浏览器的"复制到剪贴板"javascript代码
Mar 27 Javascript
js中用window.open()打开多个窗口的name问题
Mar 13 Javascript
jQuery打印图片pdf、txt示例代码
Jul 22 Javascript
JavaScript点击按钮后弹出透明浮动层的方法
May 11 Javascript
js密码强度校验
Nov 10 Javascript
jquery插件treegrid树状表格的使用方法详解(.Net平台)
Jan 03 Javascript
jQuery实现的简单拖动层示例
Feb 22 Javascript
VUE2实现事件驱动弹窗示例
Oct 21 Javascript
node.js+express+mySQL+ejs+bootstrop实现网站登录注册功能
Jan 12 Javascript
JS实现的合并多个数组去重算法示例
Apr 11 Javascript
傻瓜式解读koa中间件处理模块koa-compose的使用
Oct 30 Javascript
利用vue重构有赞商城的思路以及总结整理
Feb 21 Javascript
jQuery+ThinkPHP实现图片上传
Jul 23 #jQuery
详解vue中v-on事件监听指令的基本用法
Jul 22 #Javascript
使用vue实现通过变量动态拼接url
Jul 22 #Javascript
浅谈JavaScript窗体Window.ShowModalDialog使用
Jul 22 #Javascript
解决vue里a标签值解析变量,跳转页面,前面加默认域名端口的问题
Jul 22 #Javascript
vue props 一次传多个值实例
Jul 22 #Javascript
微信小程序动态评分展示/五角星展示/半颗星展示/自定义长度展示功能的实现
Jul 22 #Javascript
You might like
PHP 字符串编码截取函数(兼容utf-8和gb2312)
2009/05/02 PHP
解析在apache里面给php写虚拟目录的详细方法
2013/06/24 PHP
PHP输出九九乘法表代码实例
2015/03/27 PHP
JS 页面内容搜索,类似于 Ctrl+F功能的实现代码
2007/08/13 Javascript
jQuery中after的两种用法实例
2013/07/03 Javascript
jquery的attr方法禁用表单元素禁用输入内容
2014/06/23 Javascript
jquery实现的伪分页效果代码
2015/10/29 Javascript
基于js对象,操作属性、方法详解
2016/08/11 Javascript
AngularJS指令详解及示例代码
2016/08/16 Javascript
AngularJs ng-route路由详解及实例代码
2016/09/14 Javascript
AngularJS ng-repeat数组有重复值的解决方法
2016/10/23 Javascript
通过jsonp获取json数据实现AJAX跨域请求
2017/01/22 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
2017/03/08 Javascript
vue axios 二次封装的示例代码
2017/12/08 Javascript
vue实现自定义多选与单选的答题功能
2018/07/05 Javascript
详解用Webpack与Babel配置ES6开发环境
2019/03/12 Javascript
JS使用正则表达式判断输入框失去焦点事件
2019/10/16 Javascript
一篇文章入门Python生态系统(Python新手入门指导)
2015/12/11 Python
将字典转换为DataFrame并进行频次统计的方法
2018/04/08 Python
python利用smtplib实现QQ邮箱发送邮件
2020/05/20 Python
python正则表达式之对号入座篇
2018/07/24 Python
使用python批量读取word文档并整理关键信息到excel表格的实例
2018/11/07 Python
python使用 zip 同时迭代多个序列示例
2019/07/06 Python
Ubuntu18.04安装 PyCharm并使用 Anaconda 管理的Python环境
2020/04/08 Python
Python切片列表字符串如何实现切换
2020/08/06 Python
Python 实现微信自动回复的方法
2020/09/11 Python
python3 os进行嵌套操作的实例讲解
2020/11/19 Python
Flask-SocketIO服务端安装及使用代码示例
2020/11/26 Python
HTML5公共页面提取作为公用代码的方法
2020/06/30 HTML / CSS
美国高档百货Nordstrom的折扣店:Nordstrom Rack
2017/11/13 全球购物
西班牙在线宠物食品和配件商店:bitiba
2019/10/11 全球购物
几个Linux面试题笔试题
2016/08/01 面试题
商场消防演习方案
2014/02/12 职场文书
学前班评语大全
2014/05/04 职场文书
优秀管理者事迹材料
2014/05/22 职场文书
2014年大班保育员工作总结
2014/12/02 职场文书