NodeJS开发教程

《NodeJS开发教程8-事件》

2018-04-25  本文已影响6人  Codingyu

事件EventEmitter可谓是NodeJS中的重中之重!
大多数 Node.js 核心 API 都采用惯用的异步事件驱动架构,其中某些类型的对象(触发器)会周期性地触发命名事件来调用函数对象(监听器)。

例如,net.Server 对象会在每次有新连接时触发事件;fs.ReadStream 会在文件被打开时触发事件;流对象 会在数据可读时触发事件。

所有能触发事件的对象都是 EventEmitter 类的实例。 这些对象开放了一个 eventEmitter.on() 函数,允许将一个或多个函数绑定到会被对象触发的命名事件上。 事件名称通常是驼峰式的字符串,但也可以使用任何有效的 JavaScript 属性名。

EventEmitter 对象触发一个事件时,所有绑定在该事件上的函数都被同步地调用。 监听器的返回值会被丢弃。

/*事件*/
var EventEmitter=require("events");

require("events")返回的EventEmitter是一个类(或者说events模块exports导出的是一个class)然后:

/*事件*/
var EventEmitter=require("events");

const event=new EventEmitter();//创建一个事件发射器实例
//注册异步事件
event.on("customEvent",function()
{
    console.log("customEvent事件触发");
});

//触发事件
event.emit("customEvent");

我们通过 const event=new EventEmitter()得到一个实例对象event
接着可以通过event.on(eventName,callbackfunc)来注册一个异步事件
在需要触发eventName事件时使用 event.emit(eventName)进行事件的触发,事件可以注册多个相同事件的监听器,在触发该事件时,依次按照注册的顺序进行触发事件监听器的回调方法callbackfunc。

class MyEmitter extends EventEmitter{

    constructor(name)
    {
        super();
        this.name=name;
    }
    getName()
    {
        return this.name;
    }

}

const myEmitter=new MyEmitter("自定义事件发射器");
myEmitter.on("clicktest",function()
{
    //会打印:clicktest事件触发 自定义事件发射器
    console.log("clicktest事件触发",this.getName());

});
myEmitter.on("clicktest",()=>{
    //箭头函数中this指向的并不是myEmitter
    //会打印:clicktest事件触发 myEmitter父作用域中的getName()方法
    //如果把下面的this.getName=function(){}注释掉,这个事件触发后会报错,因为找不到getName()方法;
    console.log("clicktest事件触发",this.getName());
});
this.getName=function()
{
    return "myEmitter父作用域中的getName()方法";
}

//触发事件
myEmitter.emit("clicktest");
//同步与异步事件发生
myEmitter.on("asyncEvent",function()
{
    setImmediate(()=>{
        console.log("asyncEvent事件发生是异步的");
    });
    console.log("asyncEvent事件发生是同步的");
});
myEmitter.emit("asyncEvent");
console.log("看谁先执行,异步和同步");

执行输出:

asyncEvent事件发生是同步的
看谁先执行,异步和同步
asyncEvent事件发生是异步的
//只执行一次监听回调
myEmitter.on("myevent",function()
{
    console.log("myevent事件触发");
});
myEmitter.once("myevent2",function()
{
    console.log("myevent2事件触发");
});

myEmitter.emit("myevent");
myEmitter.emit("myevent");

myEmitter.emit("myevent2");
myEmitter.emit("myevent2");

执行输出:

myevent事件触发
myevent事件触发
myevent2事件触发
//当有事件注册监听时触发
myEmitter.on("newListener",function()
{
    console.log("newListener事件触发");
});

myEmitter.on("myevent",function()
{
    console.log("myevent事件触发");
});
//只执行一次监听回调
myEmitter.once("myevent2",function()
{
    console.log("myevent2事件触发");
});

执行输出

newListener事件触发
newListener事件触发
//事件移除
myEmitter.on("genEvent",handlerEvent);

function handlerEvent()
{
    console.log("genEvent事件触发");
}

myEmitter.emit("genEvent");
//移除改事件监听后,后续再emit该事件则忽略不会触发监听回调
myEmitter.removeListener("genEvent",handlerEvent);
myEmitter.emit("genEvent");

执行输出:

genEvent事件触发

nodejs性能的提升大部分原因是得益于 异步事件机制。它摒弃掉了多线程,使用单线程进行处理主逻辑(当然io操作依然是多线程处理)通过异步事件来节约cpu的等待周期,最大限度的压榨cpu资源。

上一篇 下一篇

猜你喜欢

热点阅读