详解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 相关文章推荐
DIY jquery plugin - tabs标签切换实现代码
Dec 11 Javascript
jquery限制输入字数,并提示剩余字数实现代码
Dec 24 Javascript
密码强度检测效果实现原理与代码
Jan 04 Javascript
使用javascipt---实现二分查找法
Apr 10 Javascript
如何获取网站icon有哪些可行的方法
Jun 05 Javascript
如何防止INPUT按回车自动提交表单FORM
Dec 06 Javascript
angular.js 路由及页面传参示例
Feb 24 Javascript
老生常谈jacascript DOM节点获取
Apr 17 Javascript
Bootstrap实现下拉菜单多级联动
Nov 23 Javascript
在Create React App中启用Sass和Less的方法示例
Jan 16 Javascript
使用Vue开发自己的Chrome扩展程序过程详解
Jun 21 Javascript
vue中提示$index is not defined错误的解决方式
Sep 02 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编程过程中需要了解的this,self,parent的区别
2009/12/30 PHP
PHP 之Section与Cookie使用总结
2012/09/14 PHP
深入php多态的实现详解
2013/06/09 PHP
php获取随机数组列表的方法
2014/11/13 PHP
smarty模板判断数组为空的方法
2015/06/10 PHP
PHP+Mysql+jQuery中国地图区域数据统计实例讲解
2015/10/10 PHP
详解Laravel5.6 Passport实现Api接口认证
2018/07/27 PHP
在laravel-admin中列表中禁止某行编辑、删除的方法
2019/10/03 PHP
Javascript打印网页部分内容的脚本
2008/11/17 Javascript
使用JS进行目录上传(相当于批量上传)
2010/12/05 Javascript
JS Range HTML文档/文字内容选中、库及应用介绍
2011/05/12 Javascript
Javascript的数组与字典用法与遍历对象的属性技巧
2012/11/07 Javascript
js 判断上传文件大小及格式代码
2013/11/13 Javascript
jQuery将所有被选中的checkbox某个属性值连接成字符串的方法
2015/01/24 Javascript
jQuery插件实现文件上传功能(支持拖拽)
2020/08/27 Javascript
详解JavaScript常量定义
2017/01/03 Javascript
总结几道关于Node.js的面试问题
2017/01/11 Javascript
javascript中json基础知识详解
2017/01/19 Javascript
详解angularJS+Ionic移动端图片上传的解决办法
2017/09/13 Javascript
JS实现的简单四则运算计算器功能示例
2017/09/27 Javascript
javascript中可能用得到的全部的排序算法
2020/03/05 Javascript
基于JavaScript或jQuery实现网站夜间/高亮模式
2020/05/30 jQuery
Vue项目接入Paypal实现示例详解
2020/06/04 Javascript
Python3处理文件中每个词的方法
2015/05/22 Python
Python随机数用法实例详解【基于random模块】
2017/04/18 Python
Python UnboundLocalError和NameError错误根源案例解析
2018/10/31 Python
Python3爬虫学习之应对网站反爬虫机制的方法分析
2018/12/12 Python
Python流程控制语句的深入讲解
2020/06/15 Python
使用简单的CSS3属性实现炫酷读者墙效果
2014/01/08 HTML / CSS
个人简历自我评价
2014/01/06 职场文书
电气自动化个人求职信范文
2014/02/03 职场文书
2014年小学教师工作自我评价
2014/09/22 职场文书
初中中等生评语
2014/12/29 职场文书
2016党员发展对象培训心得体会
2016/01/08 职场文书
2016幼儿教师自荐信范文
2016/01/28 职场文书
Alexa停服!网站排名将何去何从?目前还没有替代品。
2022/04/15 杂记