美文网首页我爱编程
Node.js组成及Events模块

Node.js组成及Events模块

作者: 有个水友 | 来源:发表于2017-01-10 00:24 被阅读97次

    1 Node.js的模块和包

    1.1模块

    Node.js本身提供许多模块,每个模块实现一种功能,如文件操作模块fs,构建HTTP服务的http模块等,每个模块都是一个javascript文件,可以自己编写模块。

    每一个Node.js都是一个Node.js模块,包括JavaScript文件(.js)、JSON文本文件(.json)和二进制模块文件(.node

    1.1.1 模块的使用

    模块内使用module.exportsexports对外提供接口,便于在其他模块中引入要使用的模块,新建模块module.js,并对外提供接口。

    使用exports提供接口

    function hello() {
        console.log("Hello");
    }
    
    function world() {
        console.log("World");
    }
    
    exports.hello = hello;
    exports.world = world;
    

    使用module.exports提供接口

    function Hello() {
        this.hello = function() {
            console.log("Hello");
        };
    
        this.world = function() {
            console.log("World");
        };
    }
    
    module.exports = Hello;
    
    1.1.2 引用模块

    使用require()引用创建的模块,参数是模块的路径。

    引用exports提供接口的模块

    var hello = require("./test.js");
    
    hello.hello();  //==> Hello
    hello.world();  //==> World
    
    

    引用module.exports提供接口的模块

    //module.exports导出的是Hello函数,将其保存到Test变量中
    var Test = require("./test.js");
    
    //将Test()当做构造起函数,创建对象来使用
    var demo = new Test();
    demo.hello();    //==> Hello
    demo.world();  //==> World
    

    1.2 module.exportsexports区别

    每个模块中都有一个module对象,module是当前模块的一个引用。module.exports对象是由Module系统构建的,exports可以看做module.exports对象的引用。

    require()一个模块时,module.exports的值为准,在有的情况下module.exportsexports的值不同。

    // module.exports和exports相同的情况
    var m = {};        // 表示 module
    var e = m.e = {};  // e 表示 exports, m.e 表示 module.exports
    
    m.e.a = 5;
    e.b = 6;
    
    console.log(m.e);  // Object { a: 5, b: 6 }
    console.log(e);    // Object { a: 5, b: 6 }
    
    // module.exports和exports不同的情况
    var m = {};        // 表示 module
    var e = m.e = {};  // e 表示 exports, m.e 表示 module.exports
    
    m.e = { c: 9 };    // m.e(module.exports)引用的对象被改了
    e.d = 10;
    
    console.log(m.e);  // Object { c: 9 }
    console.log(e);    // Object { d: 10 }
    

    1.2 包

    包可以将多个具有依赖关系的模块组织在一起,将多个模块封装,便于管理。

    Node.js采用CommonJS规范,一个javascript文件就是一个模块,包是一个文件夹,包内必须包含一个名为package.json的JSON文件
    包内bin文件夹内存放二进制文件,lib文件夹存放javascript文件,doc文件夹存放文档,test文件夹存放单元测试。

    1.2.1包的目录

    包的目录必须包含package.json文件,CommonJS用来描述包,应该包含以下字段:

    • name:包的名字,唯一,只能包含字符、下划线和数字;
    • version:包的版本号;
    • description:包的说明;
    • keywords:关键字数组,用于搜索;
    • homepage:项目主页;
    • bugs:提交bug的地址;
    • liciense:许可证;
    • maintainers:维护者数组;
    • contributors:贡献者数组;
    • repositories:项目仓库托管地址数组;
    • dependencies:包依赖。

    实例

    {
        "name": "Kyxy",
        "description": "Kyxy test package.",
        "version": "0.1.0",
        "keywords": [
            "kyxy",
            "nodejs"
         ],
        "maintainers": [{
            "name": "test",
            "email": "test@kyxy.com"
        }],
        "contributors": [{
            "name": "test",
            "web": "http://www.kyxy.com/"
        }],
        "bugs": {
            "mail": "test@kyxy.com",
            "web": "http://www.kyxy.com/"
        },
        "licenses": [{
            "type": "Apache License v2",
            "url": "http://www.apache.org/licenses/apache2.html"
        }],
        "repositories": [{
            "type": "git",
            "url": "http://github.com/test/test.git"
        }],
        "dependencies": { 
            "webkit": "1.2",
            "ssl": { 
                "gnutls": ["1.0", "2.0"],
                "openssl": "0.9.8"
            }
        }
    }
    

    1.3 npm包管理工具

    npm是Node.js的包管理工具,npm定义了包依赖关系标准,使用npm下载第三方包和管理本地下载的第三方包

    查询包信息
    npm info express
    安装包
    sudo npm install express
    更新包
    sudo npm update express
    卸载包
    sudo npm uninstall express


    2 Events模块

    Node.js中,许多对象会发出事件:fs.readStream 打开一个文件时会发出一个事件。所有发出的事件对象都是events.EventEmitter的实例,可以通过require("events");获得events模块。

    事件命名推荐使用驼峰命名法。将函数添加到对象,对象发出事件时,相应函数被执行(这些函数被称为监听器);先将函数赋予对象(设为监听器),在对象发出事件时调用该函数

    2.1 Class: events.EventEmitter

    通过require("events").EventEmitter获取 EventEmitter类。当EventEmitter对象遇到错误时,触发error事件

    error事件在Node.js中是一种特殊事件,(如果没有设置error事件触发的监听器),默认打印出栈跟踪器,并退出程序。

    2.2 添加监听器

    为事件添加监听器有两种方法,作用完全相同:参数事件(event),处理函数(listener)

    • emitter.addListener(event, listener) :
    • emitter.on(event, listener): 一直监听
    //import http module
    var http = require("http");
    //create a http server
    var server = http.createServer();
    
    //bind a listener for server`s request Event
    server.on("request", function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write("Tracy");
        console.log("Kyxy");
        res.end();
    });
    
    //listen ip:127.0.0.1 port:1337, if requested, execute the listener function
    server.listen(1337, "127.0.0.1");
    console.log('Server running at http://127.0.0.1:1337/');
    

    运行上述代码,在浏览器地址栏输入127.0.0.1:1337,可以看到Tracy,同时控制台输出Kyxy

    2.3 只执行一次的监听器

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

    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/');
    

    运行上述代码,在浏览器地址栏输入127.0.0.1:1337,可以看到Tracy,同时控制台输出Kyxy再刷新页面,就不会再显示,因为事件只会执行一次。

    2.4 移除监听器

    使用emitter.removeListener(event, listener)方法移除为对象的request事件绑定的处理函数。

    //import http module
    var http = require("http");
    //create a http server
    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();
    }
    
    //bind a listener for server`s request Event
    server.on("request", callback);
    
    //remove a listener for server`s request Event
    server.removeListener("request", callback);
    
    server.on("request", function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/json' });
        res.write("I`m back");
        console.log("LMD");
        res.end();
    });
    
    //listen ip:127.0.0.1 port:1337, if requested, execute the listener function
    server.listen(1337, "127.0.0.1");
    console.log('Server running at http://127.0.0.1:1337/');
    

    运行上述代码,在浏览器地址栏输入127.0.0.1:1337,可以看到Im back,同时控制台输出LMD,但是没有Hello World,因为监听器callback`被移除了。

    2.4 移除所有监听器

    使用emitter.removeAllListeners([event]),移除对象上监听event事件的所有监听器

    //import http module
    var http = require("http");
    //create a http server
    var server = http.createServer();
    
    function talk(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write("haha");
        console.log("xixi");
        res.end();
    }function fruit(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write("apple");
        console.log("leomon");
        res.end();
    }
    
    //bind  listeners for server`s request Event
    server.on("request", talk);
    server.on("request", fruit)
    //remove  listeners from server`s request Event
    server.removeAllListeners("request");
    
    server.on("request", function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/json' });
        res.write("I`m back");
        console.log("LMD");
        res.end();
    });
    
    //listen ip:127.0.0.1 port:1337, if requested, execute the listener function
    server.listen(1337, "127.0.0.1");
    console.log('Server running at http://127.0.0.1:1337/');
    

    移除绑定在server上的所有事件监听器,所以只显示Im back,输出LMD`。

    2.5 设置监听器的最大绑定数

    emitter.setMaxListeners(n)可以设置同一事件可以绑定的监听器的最大数目,默认情况下,超过10个就会提示警告信息(可以帮助找到内存泄漏的地方),不是所有的事件触发器都限制在10个,可以通过这个方法设置,如果设置为0就是无限制

    2.6 自定义事件

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

    //import http module
    var http = require("http");
    //create a http server
    var server = http.createServer();
    
    server.on("myevent", function(arg) {
        console.log(arg);
    });
    
    server.emit("myevent", "Kyxy");
    
    server.on("request", function(req, res) {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write("Tracy");
        res.end();
    });
    
    //listen ip:127.0.0.1 port:1337, if requested, execute the listener function
    server.listen(1337, "127.0.0.1");
    console.log('Server running at http://127.0.0.1:1337/');
    

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

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

    var http = require("http");
    var events = require("events");
    var server = http.createServer();
    
    server.on("request", function(req, res) {
        res.writeHead(200, {"Content-Type": "text/plain"});
        res.write("kyxy");
        console.log("kyxy");
        res.end();
    });
    
    server.on("request", function(req, res) {
        res.writeHead(200, {"Content-Type": "text/plain"});
        res.write("Tracy");
        console.log("Tracy");
        res.end();
    });
    
    server.listen(1337, "127.0.0.1");
    console.log('Server running at http://127.0.0.1:1337/');
    
    var num = events.EventEmitter.listenerCount(server, "request");
    console.log(num); //2
    

    控制台界面输出了数字2,因为server绑定了两个监听器到'request'事件。

    相关文章

      网友评论

        本文标题:Node.js组成及Events模块

        本文链接:https://www.haomeiwen.com/subject/xkwhbttx.html