Node.js事件处理机制

Posted 橘猫吃不胖~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js事件处理机制相关的知识,希望对你有一定的参考价值。

Node.js事件处理机制

1 概述

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

由于nodejs是单线程运行的,所以nodejs需要借助事件轮询,不断去查询事件队列中的事件消息,然后执行该事件对应的回调函数,有点类似windows的消息映射机制。

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

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

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

Node.js的事件机制中主要有三类角色:事件(Event)、事件发射器(EventEmitter)、事件监听器(EventListener)

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

// 引入 events 模块
let events = require("events");
// 创建 eventEmitter 对象
let eventEmitter = new events.EventFmitter();
// 绑定事件及事件的处理程序
eventEmitter.on("eventName", eventHandler);
// 触发事件
eventEmitter.emit("eventName");

2 EventEmitter类–事件发射器

在Node.js的用于实现各种事件处理的events模块中,定义了一个EventEmitter类。所有可能触发事件的对象都是一个集成了EventEmitter类的子类的实例对象,在Node.js中,为EventEmitter类定义了许多方法,所有与对象的事件处理函数的绑定及解除相关的处理均依靠这些方法的调用来执行。

3 EventEmitter类的各种方法

event:代表事件名,listener:代表事件处理函数

方法名与参数描述
addListener(event,listener)事件监听函数
on(event, listener)对指定对象绑定事件处理函数(addListener方法的别名)
once(event, listener)对指定对象指定只执行一次的事件处理函数
removeListener(event, listener)删除事件
setMaxListeners(n)指定对象处理函数的最大数量,n为正数值,代表最大的可指定事件处理函数的数量
listeners(event)获取指定对象的所有事件处理函数
emit(event, [arg1], [arg2], […])手动触发指定事件

1、EventEmitter类的on方法:

示例:当服务器接收到客户端请求时,在控制台窗口中输出客户端请求的目标地址(URL地址),并使用响应对象的end方法立即结束响应

const http = require("http");

//创建服务器对象
let server = http.createServer();

//绑定事件
server.on("request", function (req, res) 
    console.log("请求地址:", req.url);
    res.end("Hello World");
)

//服务器启动监听
server.listen(8089, "127.0.0.1");

在浏览器网址中输入:127.0.0.1:8089,就会显示Hello World。

同时在服务器后台会显示以下信息:

示例:也可以通过多个on方法的执行来对同一个事件绑定多个事件处理函数

const http = require("http");

//创建服务器对象
let server = http.createServer();

//给服务器对象绑定事件request
server.on("request", function (req, res) 
    console.log("接收到客户端请求")
)

//绑定事件
server.on("request", function (req, res) 
    console.log("处理客户请求");
    console.log("请求地址:", req.url);
    res.end();
)

server.on("request", function (req, res) 
    console.log("发送响应完毕");
)

//服务器启动监听
server.listen(8089, "127.0.0.1");

在浏览器网址中输入:127.0.0.1:8089,可以成功加载页面,但是由于我们什么内容都没有写,因此显示空白页面。

在服务器后台会显示以下信息:

2、EventEmitter类的once方法
once方法与on方法类似,作用均为对指定事件绑定事件处理函数,区别在于,当事件处理函数执行一次后立即被结束,即该事件处理函数只会被执行一次。once方法所用参数与on方法所用参数相同。

示例代码:

let http = require("http");
let server = http.createServer();

server.once("request", function (req, res) 
    console.log("接收到客户端请求");
)

server.on("request", function (req, res) 
    console.log("处理客户端请求");
    console.log("请求地址:", req.url);
    res.end();
)

server.once("request", function (req, res) 
    console.log("发送响应完毕");
)

server.listen(8089, "127.0.0.1");

在浏览器网址中输入:127.0.0.1:8089,成功加载页面。

服务器后台显示以下信息:

3、使用removeListener方法取消事件处理函数

示例代码:

const http = require("http");
let server = http.createServer();

let testFunction = function (req, res) 
    console.log("发送响应完毕");


server.on("request", function (req, res) 
    console.log("接收到客户端请求")
)

server.on("request", function (req, res) 
    console.log("处理客户请求");
    console.log("请求地址:", req.url);
    res.end();
)

server.on("request", testFunction);

//删除
server.removeListener("request", testFunction);
server.listen(8089, "127.0.0.1");



4、自定义事件并将其触发

示例代码:

var http = require("http");
var server = http.createServer();

server.on("request", function (req, res) 
    console.log("请求地址:", req.url);
);

//自定义事件
server.on("customEvent", function (arg1, arg2, arg3) 
    console.log("自定义事件被触发");
    console.log(arg1);
    console.log(arg2);
    console.log(arg3);
);

//触发自定义事件
server.emit("customEvent", "橘猫吃不胖", "今天天气好", "小鱼水里游");
server.listen(8089, "127.0.0.1");


后台显示以下信息:

4 错误捕获

事件处理过程中抛出的错误,可以使用try…catch捕获。

示例代码:

let EventEmitter = require("events").EventEmitter;
let emitter = new EventEmitter();

emitter.on("beep", function () 
    console.log("beep");
)
emitter.on("beep", function () 
    throw Error("oops");
)
emitter.on("beep", function () 
    console.log("beep again");
)
console.log("before emit");
try 
    emitter.emit("beep");
 catch (err) 
    console.log("错误:", err.message);

console.log("after emit");


本例中,beep一共绑定了3个监听函数。其中,第二个监听函数会抛出错误。

以上是关于Node.js事件处理机制的主要内容,如果未能解决你的问题,请参考以下文章

Websocket 内存泄漏 node.js。事件发射器?

Node.js的事件处理机制

Node基础知识笔记

Node.js知识点整理之----基础知识----事件处理机制及事件环机制

node.js之事件机制

Node.js自定义对象事件监听与发射