简单实现EventEmitter

简单实现EventEmitter

尝试做了一下

  • 原理

    • 在一个页面监听某个时间
    • 在另一个页面触发
  • 源码

    Observer.js

class Observer {
     
  constructor() {
     
    // initial the handlers as a empty array
    this.handlers = [];
  }

  // if you find one already exist in handlers, then return the index and the item
  _find(name) {
     
    let obj = {
     };
    const flag = this.handlers.some((handler, index) => {
     
      if (handler.name === name) {
     
        obj = {
     
          item: handler,
          index,
        }
        return true;
      }
      return false;
    });
    if (!flag) return false;
    return obj;
  }

  // add listener here
  on(name, handler, _once = false) {
     
    const obj = this._find(name);
    if (!obj) {
     
      this.handlers.push({
     
        name,
        handler,
        _once,
      });
    } else {
     
      // if find old, replace it with new one
      this.handlers.splice(obj.index, 1, {
     
        ...obj.item,
        handler,
        _once,
      });
    }
  }

  // here add an listener only could be emit once
  once(name, handler) {
     
    this.on(name, handler, true);
  }

  // emit hanlder here
  emit(name) {
     
    const obj = this._find(name);
    if (obj) {
     
      const {
      item: _item } = obj;
      if (_item.handler) {
     
        // if only once, remove it after it emit
        if (_item._once) {
     
          this.handlers = this.handlers.filter(handler => handler.name !== _item.name);
        }
        // emit the handler
        _item.handler();
      } else {
     
        // throw the error
        throw new Error('Opps, occured an error, handler is undefined!');
      }
    }
  }

  // clear all the handlers
  removeAll() {
     
    this.handlers = [];
  }

}
module.exports = Observer;

index.js

const EventEmitter = require('./observer');

function init() {
     
  const listener = new EventEmitter();

  // tested
  listener.on('test', () => {
     
    console.log('test');
  });

  // tested
  listener.once('test', () => {
     
    console.log('after');
  });
  
  listener.emit('test');
  listener.emit('test');
  listener.removeAll(); // tested
}
init();

你可能感兴趣的