实现Event

# 实现Event

/**
 * 考察设计模式 => 发布订阅模式. 实现 Event 类, 支持 once, on, off, emit
 */
class Event {
 listeners = {};

 on(type, fn) {
  if (this.listeners[type]) {
   this.listeners[type].push(fn);
  } else {
   this.listeners[type] = [fn];
  }
 }

 emit(type, ...args) {
  this.listeners[type].forEach((fn) => {
   fn.apply(this, args);
  });
 }

 off(type, fn) {
  const index = this.listeners[type].indexOf(fn);
  this.listeners[type].splice(index, 1);
 }

 once(type, fn) {
  const cb = (...args) => {
   fn.apply(this, args);
   this.off(type, fn);
  };
  this.on(type, cb)
 }
}

const event = new Event();

event.on('say', console.log);
event.once('eat', console.log);

event.emit('say', 'good bye')

event.emit('eat', 'dog', 'cat');
event.emit('eat', 'cat', 'flish');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 单对象写法 Event 就相当于事件中心
const Event = function () {
 // 使用闭包的好处:把EventPool私有化,外界无法访问EventPool
 const EventPool = new Map();
 // 使用 es6 map 来存储 event.callback 键值对

 const isFunction = func => typeof func === 'function';

 const on = (event, callback) => {
  // 注册事件
  EventPool.get(event) || EventPool.set(event, []);

  if (isFunction(callback)) {
   EventPool.get(event).push(callback);
  }
  else {
   throw new Error('callback not is function')
  }
 };

 const addEventListener = (event, callback) => {
  // on 方法别名
  on(event, callback);
 };

 const emit = (event, ...args) => {
  // 触发(发布)事件
  // 让事件的触发为一个异步的过程,即排在同步代码后执行
  // 也可以 setTimeout(fn, 0)
  Promise.resolve().then(() => {
   let funcs = EventPool.get(event);
   if (funcs) {
    funcs.forEach(f => f(...args));
   } else {
    throw new Error(`${event} not register`)
   }
  })
 };

 const send = (event, ...args) => {
  // emit 方法别名
  emit(event, ...args)
 };

 const removeListener = event => {
  // 删除事件
  Promise.resolve(() => {
   // 删除事件也为异步的过程
   if (event) {
    EventPool.delete(event);
   } else {
    throw new Error(`${event} not register`)
   }
  })
 };

 return {
  on, emit, addEventListener, send
 }
}();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class EventEmiter {
 constructor() {
  this._EventPool = new Map();
 }

 on(event, callback) {
  this._EventPool.get(event) || this._EventPool.set(event, []);

  if(typeof callback === 'function') {
   this._EventPool.get(event).push(callback);
  }
  else {
   throw new Error('callback not is function')
  }
 }

 addEventListener(event, callback) {
  this.on(event, callback)
 }

 emit(event, ...args) {
  Promise.resolve().then(() => {
   let funcs = this._EventPool.get(event);
   if (funcs) {
    funcs.forEach(f => f(...args))
   } else {
    throw new Error(`${event} not register`)
   }
  })
 }

 send(event, ...args) {
  this.emit(event, ...args)
 }

 removeListener(event) {
  Promise.resolve().then(() => {
   if (event) {
    this._EventPool.delete(event)
   } else {
    throw new Error(`${event} not register`)
   }
  })
 }
}

// (module) && (module.exports) && (module.exports = {Event, EventEmiter})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
上次更新: 2022/7/11 上午12:35:01