zoukankan      html  css  js  c++  java
  • nodeJS中的事件机制

    events模块是node的核心模块,几乎所有常用的node模块都继承了events模块,比如http、fs等。本文将详细介绍nodeJS中的事件机制

    EventEmitter

    多数 Node.js 核心 API 都是采用惯用的异步事件驱动架构,其中某些类型的对象(称为触发器)会周期性地触发命名事件来调用函数对象(监听器)。例如,一个net.Server对象会在每次有新连接时触发一个事件;一个fs.ReadStream 会在文件被打开时触发一个事件;一个stream会在数据可读时触发事件。

    【EventEmitter】
    EventEmitter 类由 events 模块定义和开放的,所有能触发事件的对象都是 EventEmitter 类的实例

    var EventEmitter = require('events');
    /*
    { [Function: EventEmitter]
      EventEmitter: [Circular],
      usingDomains: false,
      defaultMaxListeners: [Getter/Setter],
      init: [Function],
      listenerCount: [Function] }
     */
    console.log(EventEmitter);
    

    events模块的EventEmitter属性指向该模块本身

    var events = require('events');
    console.log(events.EventEmitter === events);//true
    

    EventEmitter是一个构造函数,可以用来生成事件发生器的实例emitter

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    /*
    EventEmitter {
     domain: null,
     _events: {},
     _eventsCount: 0,
     _maxListeners: undefined }
    */
    console.log(emitter);
    

    方法

    【emitter.emit(eventName[, …args])】

    eventName <any>
    ...args <any>
    

    该方法按监听器的注册顺序,同步地调用每个注册到名为eventName事件的监听器,并传入提供的参数。如果事件有监听器,则返回true,否则返回false

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.on('test1',function(){});
    console.log(emitter.emit('test1'));//true
    console.log(emitter.emit('test2'));//false
    

    【emitter.on(eventName, listener)】

    该方法用于添加listener函数到名为eventName的事件的监听器数组的末尾

    eventName <any> 事件名
    listener <Function> 回调函数
    

    注意:不会检查listener是否已被添加。多次调用并传入相同的eventName和listener会导致listener被添加与调用多次

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.on('test',function(){
        console.log(1);
    });
    emitter.on('test',function(){
        console.log(2);
    });
    emitter.emit('test');//1 2
    

    该方法返回一个 EventEmitter 引用,可以链式调用

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.on('test',function(){
        console.log(1);
    }).on('test',function(){
        console.log(2);
    });
    emitter.emit('test');//1 2
    

    【emitter.addListener(eventName, listener)】

    emitter.on(eventName, listener) 的别名

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.addListener('test',function(){
        console.log(1);
    });
    emitter.emit('test');//1
    

    【emitter.prependListener()】

    与on()方法不同,prependListener()方法可用于将事件监听器添加到监听器数组的开头

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.on('test',function(){
        console.log(1);
    }).prependListener('test',function(){
        console.log(2);
    });
    emitter.emit('test');//2 1
    

    【emitter.once(eventName, listener)】

    该方法添加一个单次 listener 函数到名为 eventName 的事件。 下次触发 eventName 事件时,监听器会被移除,然后调用

    eventName <any> 事件名
    listener <Function> 回调函数
    
    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.on('test',function(){
        console.log(1);
    }).once('test',function(){
        console.log(2);
    });
    emitter.emit('test');//1 2
    emitter.emit('test');//1
    

    【emitter.prependOnceListener() 】

    该方法用于将事件监听器添加到监听器数组开头。下次触发eventName事件时,监听器会被移除,然后调用

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.on('test',function(){
        console.log(1);
    }).prependOnceListener('test',function(){
        console.log(2);
    });
    emitter.emit('test');//2 1
    emitter.emit('test');//1
    

    【emitter.removeAllListeners([eventName])】

    eventName <any>
    

    移除全部或指定 eventName 的监听器,返回一个 EventEmitter 引用,可以链式调用

    注意:在代码中移除其他地方添加的监听器是一个不好的做法,尤其是当 EventEmitter 实例是其他组件或模块(如 socket 或文件流)创建的

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.on('test',function(){
        console.log(1);
    }).removeAllListeners('test');
    emitter.emit('test');//''
    

    【emitter.removeListener(eventName, listener)】

    eventName <any>
    listener <Function>
    

    从名为 eventName 的事件的监听器数组中移除指定的 listener

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    emitter.on('test',function(){
        console.log(1);
    }).prependListener('test',function(){
        console.log(2);
    });
    emitter.emit('test');//2 1
    

    注意:removeListener最多只会从监听器数组里移除一个监听器实例。如果任何单一的监听器被多次添加到指定eventName的监听器数组中,则必须多次调用removeListener才能移除每个实例

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    function show(){
        console.log(1);
    }
    emitter.on('test',show).on('test',show).removeListener('test',show);
    emitter.emit('test');//'1'
    

    注意:一旦一个事件被触发,所有绑定到它的监听器都会按顺序依次触发。这意味着,在事件触发后、最后一个监听器完成执行前,任何 removeListener() 或 removeAllListeners() 调用都不会从 emit() 中移除它们。 随后的事件会像预期的那样发生

    因为监听器是使用内部数组进行管理的,所以调用它会改变在监听器被移除后注册的任何监听器的位置索引。 虽然这不会影响监听器的调用顺序,但意味着由 emitter.listeners() 方法返回的监听器数组副本需要被重新创建

    var EventEmitter = require('events');
    var emitter = new EventEmitter();
    function show1(){
        console.log(1);
        emitter.removeListener('test',show2);
    }
    function show2(){
        console.log(2);
    }
    emitter.on('test',show1).on('test',show2);
    emitter.emit('test');//1 2
    emitter.emit('test');//1
    
  • 相关阅读:
    约瑟夫问题
    [bzoj] 2049 洞穴勘探 || LCT
    [bzoj] 1597 土地购买 || 斜率优化dp
    [usaco] 2008 Dec Largetst Fence 最大的围栏 2 || dp
    [LNOI] 相逢是问候 || 扩展欧拉函数+线段树
    [bzoj] 1588 营业额统计 || Splay板子题
    [hdu] 5115 Dire Wolf || 区间dp
    [poj] 1651 Multiplication Puzzle || 区间dp
    [bzoj] 1090 字符串折叠 || 区间dp
    [bzoj] 1068 压缩 || 区间dp
  • 原文地址:https://www.cnblogs.com/spiritmark/p/13010110.html
Copyright © 2011-2022 走看看