• nodejs模块——Event模块


    Nodejs中不存在浏览器中冒泡,捕获这些行为,Nodejs中实现了events这个模块,Nodejs中大多数模块都集成了这个模块,所以events是Nodejs中最重要的一个模块。

    events只对外暴露一个对象,就是EventEmitter,EventEmitter作用只有2个,分别是:事件的发射和事件的监听。

    Node.js中,很多对象会发出事件。如,fs.readStream打开文件时会发出一个事件。 

    所有发出事件的对象都是events.EventEmitter的实例,可以通过require("event");获得event模块。

    监听器函数(listeners)可以添加给对象,对象发出事件时,对应的函数就会被执行。在监听器函数中,this引用的是它(监听器函数)

    一、Class:events.EventEmitter

    通过require('events').EventEmitter得到EventEmitter类。

    当EventEmitter对象遇到错误时,通常会触发error事件。error事件在Nodejs中是一种特殊情况,如果没有监听器,那么默认会打印出栈跟踪器并退出程序。

    二、添加监听器

     为事件绑定事件处理程序,可以用emitter.addListener(event,listener)和emitter.on(event,listener),它们作用完全一样。传入参数是事件(event)和处理函数(listener)。

    demo:test1.js内容如下

    var http = require('http');
    var server = http.createServer();
    
    // 为request事件绑定处理函数
    // 也可以使用server.addListener
    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou');
        console.log('shiyanlou');
        res.end();
    });
    
    server.listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');

    三、只执行一次的监听器

    使用 emitter.once(event,listener)绑定的事件监听器只执行一次,然后就会被删除掉。

    demo:test2.js内容如下

    var http = require('http');
    var server = http.createServer();
    
    // 为request事件绑定处理函数,事件只会执行一次
    server.once('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou');
        console.log('shiyanlou');
        res.end();
    });
    
    server.listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');

    四、移除监听器

    移除监听器使用emitter.removeListener(event,listener); 

    demo:test3.js内容如下

    var http = require('http');
    var server = http.createServer();
    
    function callback(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('Hello World');
        console.log('Hello World');
        res.end();
    }
    
    server.on('request', callback);
    
    // 移除绑定的监听器callback
    server.removeListener('request', callback);
    
    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou');
        console.log('shiyanlou');
        res.end();
    });
    
    server.listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');

    运行结果只显示shiyanliu,不显示hello world,因为“hello world”的监听器被移除了。
    错误的移除事件不能移除匿名的事件处理程序,必须像上面一样移除具名函数。

    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou');
        console.log('shiyanlou');
        res.end();
    });
    //错误的移除事件方法
    server.removeListener('request',function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou');
        console.log('shiyanlou');
        res.end();
    });

    五、移除所有监听器

    移除所有监听器使用emitter.removeAllListener([event]) 。需要传入某种类型的事件参数,不传的话会把所有类型的事件监听都移除掉

    demo:test4.js内容如下:

    var http = require('http');
    var server = http.createServer();
    
    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou,111');
        console.log('shiyanlou,111');
        res.end();
    });
    
    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou,222');
        console.log('shiyanlou,222');
        res.end();
    });
    
    // 移除绑定的所有监听器
    server.removeAllListeners('request');
    // 移除后再绑定一个有监听器
    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou');
        console.log('shiyanlou');
        res.end();
    });
    
    server.listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');

    浏览器只输出shiyanlou

    六、设置监听器最大绑定数

    EventEmitter支持多个事件监听器,最大值是10。即可用为某个事件添加10个监听函数,做10件事情。默认情况下,超过10个就好警告提示,

    这能帮我们快速找到内存泄露的地方。

    显然,不是所有的事件触发器都限制在10个监听器,通过emitter.setMaxLisstener(n) 可以设置同一事件的监听器最大绑定数,如果设置为0就是无限制

    七、自定义事件

    使用emitter.emit(event,[arg1],[arg2],[...]) 可以触发自定义的事件。

    demo:test5.js内容如下

    var http = require('http');
    var server = http.createServer();
    
    // 绑定自定义事件myevent
    server.on('myevent', function(arg) {
        console.log(arg);
    });
    
    // 触发自定义事件
    server.emit('myevent', 'shiyanlou');
    
    server.listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');

    运行结果在console界面输出shiyanlou,说明触发自定义事件成功。

    八、查看事件绑定的监听器个数

    使用EventEmitter.listenerCount(emitter,event) 可以查看事件监听器数量。

    也可以用emitter.listeners('event').length;来查看。

    demo:test6.js内容如下

    var http = require('http');
    var events = require('events'); // 加载events模块
    var server = http.createServer();
    
    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou,111');
        console.log('shiyanlou,111');
        res.end();
    });
    
    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou,222');
        console.log('shiyanlou,222');
        res.end();
    });
    
    server.listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');
    
    //2种方法 查看server绑定的'request'事件的监听器个数
    var num = events.EventEmitter.listenerCount(server, 'request');
    var num2=server.listeners('request').length;
    console.log(num);
    console.log(num2);

    2种方法运行结果都输出了2,因为server绑定了两个监听器到"request"事件。

    九、排错

     Error:write after end【update20170327】

    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou,111');
        console.log('shiyanlou,111');
        res.end();
    });
    
    server.on('request', function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('shiyanlou,222');
        console.log('shiyanlou,222');
        res.end();
    });

    Once a writable stream is closed, it cannot accept anymore data。server绑定了2个request事件处理程序,第一个在res.write()后调用了res.end()结束了写入流,所以再次调用res.write('shiyanlou,222');就会报错,可以注释掉第一end()调用。

    本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/5035522.html有问题欢迎与我讨论,共同进步。

    // 移除绑定的所有监听器
  • 相关阅读:
    POJ 1721 CARDS(置换群)
    HDU 4609 3-idiots(FFT)
    BZOJ 4259 残缺的字符串(FFT)
    HDU 5763 Another Meaning(FFT)
    BZOJ 4503 两个串(FFT)
    hihoCoder 1388 Periodic Signal(FFT)
    HDU 5823 color II(FWT)
    HDU 5768 Lucky7(CRT+容斥原理)
    HDU 5446 Unknown Treasure(Lucas定理+CRT)
    HDU 5741 Helter Skelter(构造法)
  • 原文地址:https://www.cnblogs.com/starof/p/5035522.html
Copyright © 2020-2023  润新知