码迷,mamicode.com
首页 > 其他好文 > 详细

使用原生代码实现一个Events模块,可以实现自定义事件的订阅、触发、移除功能

时间:2019-12-22 16:31:09      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:code   function   class   传参数   ons   length   bsp   type   ==   

function Events() {
  // 放置所有添加的 监听事件
  this._events = {}
}
Events.prototype = {
  on: function (name, fn, ...argOrg) {
    // 必传参数验证
    if (!name || !fn) {
      throw new Error(`[Events TypeError] Failed to execute Events on ${name} : 2 arguments required`)
      return
    }
    // 阻止重复添加相同的监听
    let fns = this._events[name] || []
    if(fns.find(item=> item.fnOrg===fn)){
      return;
    }
    this._events[name] = fns.concat({
      fn: arg => fn.apply(null, [...argOrg, ...arg]),
      fnOrg:fn
    })
  },
  once: function (name, fn, ...argOrg) {
    const onFn = (...arg) =>{
      fn.apply(null, arg)
      this.off(name, onFn)
    }
    this.on(name, onFn, ...argOrg)
  },
  emit: function (name, ...arg) {
    (this._events[name]||[]).forEach(item =>{
      item.fn(arg)
    })
  },
  off: function (name,fn) {
    // 无参数 : 清掉所有监听
    if(!arguments.length){
      this._events = Object.create(null)
    }
    // 一个参数 : 清掉该事件名下所有监听
    if(arguments.length==1){
      delete this._events[name]
    }
    let fns = this._events[name];
    if(!fns || !fns.length)return;
    this._events[name] = (fns||[]).filter(item=> {
      return item.fnOrg !== fn
    });
  }
}
// 调用demo
const event = new Events();
const fn1 = (...args)=>console.log(I want sleep1,...args)
const fn2 = (...args)=>console.log(I want sleep2,...args)
// part1: 添加多次监听
event.on(sleep, fn1, 1, 2, 3);
event.on(sleep, fn2, 4, 5, 6);
event.emit(sleep, 7,8,9);
// 输出
// I want sleep1 1 2 3 4 5 6
// I want sleep2 1 2 3 4 5 6

// part2:once监听 只触发一次
event.once(sleep1, fn1, 11, 12);
event.emit(sleep1,13);
event.emit(sleep1,13);
// 输出
// I want sleep1 11 12 13

// part3: 重复监听“相同回调”无效(匿名函数除外)
event.on(sleep2, fn2, 22);
event.on(sleep2, fn2, 23);
event.emit(sleep2,25);
// 输出
// I want sleep2 22 25

// part3: 清除监听
event.off(sleep2, fn2);
event.off(sleep1); // 清除该事件下所有监听
event.off(); // 全部清除
event.emit(sleep2,25);
// 输出
//

 

使用原生代码实现一个Events模块,可以实现自定义事件的订阅、触发、移除功能

标签:code   function   class   传参数   ons   length   bsp   type   ==   

原文地址:https://www.cnblogs.com/liujinyu/p/12079961.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!