Structure-study-Node(util、events)

321 阅读1分钟

util

Node提供的一些工具函数

util.inherits(ctor,superCtor)

继承 实现原理是通过 Object.setPrototypeOf(ctor.prototype, superCtor.prototype);

    function Parent(){

    }

    function Child(){
        Parent.call(this)
    }

    inherits(Child,Parent)

util.inpsect

将对象转换为字符串

   console.log(util.inspect(Array.prototype,{showHidden:true})); 

util.promisify

将异步方法转换promise化

    const promisify = fn => (...args) =>{
        return new Promise((resolve,reject)=>{
            fn(...args,function(err){
                if(err) reject(err)
                resolve()
            })
        })
    }

event

发布订阅模块 核心方法 on emit once newListener off

基本使用

    let EventEmitter = require("events");
    let util = require('util');

    function Girl (){
    }
    // 继承
    util.inherits(Girl,EventEmitter);

    let girl = new Girl;

    girl.on('newListener',(type)=>{ // 监听到用户做了哪些监听
        console.log(type)
        if(type === '失恋'){ 
            process.nextTick(()=>{
                girl.emit(type);
            })
        }
    })
    let fn1 = function(){ // 默认这个方法在调用的时候
        console.log('监听到了 执行')
    }
    girl.once('失恋',fn1); // this.on('失恋',one); one.fn1
    girl.off('失恋',fn1);  // one.fn1 != fn1
    girl.once('失恋',function(){ // 默认这个方法在调用的时候
        console.log('监听到了 执行')
    })

    girl.emit('失恋');

具体实现

注意newListener 和 once的实现

    function EventEmitter(){
        // 创建一个干净的对象  没有prototype
        this._events = Object.create(null);
    }
    EventEmitter.prototype.on = function(eventName,callback){
        // 不管任何人 调用了on方法 都可以增加_events
        if(!this._events) this._events = Object.create(null);
        // 监听绑定的事件 不是newLister就调用newListener
        if(eventName !== 'newListener'){
            this.emit('newListener',eventName);
        }

        if(this._events[eventName]){
            this._events[eventName].push(callback);
        }else{
            this._events[eventName] = [callback];
        }
    }
    EventEmitter.prototype.once = function(eventName,callback){
        // 绑定 执行后 删除
        let one = ()=>{ // 2) 会触发one函数
            callback();// 触发原有的逻辑
            // 删除自己
            this.off(eventName,one); // 在将one删除掉
        }
        one.l = callback; // 用自定义属性 保存原有的绑定函数 没有这步 当off的时候取消的是one函数 而不是callback回调
        this.on(eventName,one); // 1)  先绑定
    }
    EventEmitter.prototype.off = function(eventName,callback){
        if(this._events[eventName]){
            this._events[eventName] = this._events[eventName].filter(fn=>{
                return fn != callback && fn.l !== callback
            })
        }
    }
    // {'女生失恋':[fn1,fn2]}
    EventEmitter.prototype.emit= function(eventName,...args){
        if(this._events[eventName]){
            this._events[eventName].forEach(fn => fn(...args));
        }
    }

    module.exports = EventEmitter;