Node.js事件循环

Node.js事件循环

参考https://www.runoob.com/nodejs/nodejs-event-loop.html
Node.js本身是单进程单线程的应用程序,但是V8引擎提供了可异步执行的回调接口,通过这些接口可以处理大量的并发。

  • Node.js几乎每一个API都持支回调函数。
  • Node.js几乎所有事件机制都是使用观察者模式实现。
  • Node.js的单线程类似于进入了一个while(true)事件循环,直到没有事件观察者才会退出循环。
  • 每个异步事件都会生成一个事件观察者,如果有事件发生就调用该回调函数。

事件驱动程序

Node.js使用事件驱动模型,当服务器接收到请求,就先把它关闭进行处理,然后去处理下一个请求。当这个请求完成,它会被放回处理队列,当到达队列开头,这个处理结果就会被返回给用户。

这个模型非常高效且可拓展性非常强,因为服务器一直在接收请求而不等待任何读写等IO操作(即非阻塞式IO或事件驱动IO)。
在事件驱动模型中,会产生一个主循环来用于监听事件(类似于上面提到的while(trur)事件循环),每当检测到异步事件就会产生一个事件观察者并触发回调函数。


事件相当于一个主题(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应用是如何工作的?

在Node应用程序中,执行异步操作的函数将回调函数作为最后一个参数,回调函数接收错误对象作为第一个参数。
例如,使用input.txt作为可读取的文本文件,内容如下:

  菜鸟官网地址:www.runoob.com

创建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('执行完毕');

结果:

  • 上面的程序中的readFile()是异步读取文件的函数,如果执行过程中发生错误,错误对象err会作为回调函数的第一个参数被传入,如果没有错误则跳过。
  • 如果input.txt不存在,就会发生错误,这时错误对象的栈信心会被打印出来:
posted @ 2020-12-26 09:45  pangqianjin  阅读(117)  评论(0)    收藏  举报