Skip to content

Instantly share code, notes, and snippets.

@LeeeeeeM
Last active May 22, 2019 11:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LeeeeeeM/21f51562c6d7f3cf14a52dea42275e49 to your computer and use it in GitHub Desktop.
Save LeeeeeeM/21f51562c6d7f3cf14a52dea42275e49 to your computer and use it in GitHub Desktop.
Event实现trigger、on、off、once
function Event() {
this.fnMap = {};
}
Event.prototype.on = function(type, fn) {
var fns = this.fnMap[type] || (this.fnMap[type] = [])
fns.push(fn);
return this;
};
Event.prototype.off = function(type, fn) {
var fns = this.fnMap[type];
if (fns) {
for (var i = fns.length; i >= 0; --i) {
if (fns[i] === fn) {
fns.splice(i, 1);
}
}
}
return this;
};
Event.prototype.trigger = function(type, data) {
var fns = this.fnMap[type];
if (fns) {
for (var i = 0; i < fns.length; i++) {
fns[i].call(this, data);
}
}
};
Event.prototype.once = function(type, fn) {
var fns = this.fnMap[type] || (this.fnMap[type] = [])
var self = this;
var wrapper = function() {
fn.apply(self, arguments);
self.off(type, wrapper);
};
fns.push(wrapper);
};
@LeeeeeeM
Copy link
Author

LeeeeeeM commented May 22, 2019

今天重新写了个EventEmitter,发现了错误。

function Event() {
  this.fnMap = {}
}

Event.prototype.on = function (type, fn) {
  const fnList = this.fnMap[type] = this.fnMap[type] || []
  fnList.push(fn)
  return this
}

Event.prototype.off = function (type, fn) {
  const fnList = this.fnMap[type] || []
  for (let i = fnList.length - 1; i >= 0; i--) {
    if (fnList[i] === fn) {
      fnList.splice(i, 1)
    }
  }

  return this
}

Event.prototype.once = function (type, fn) {
  const fnList = this.fnMap[type] = this.fnMap[type] || []

  const wrapper = (...args) => {
    fn.call(this, ...args)
    this.off(type, wrapper)
  }

  fnList.push(wrapper)

  return this
}

Event.prototype.emit = function (type, ...args) {

  // keyPoint
  const fnList = (this.fnMap[type] || []).slice()
  // keyPoint
  for (let i = 0; i < fnList.length; i++) {
    fnList[i].call(this, ...args)
  }
  return this
}

let event = new Event()


event.on('click', function(...args) {
  console.log(1, ...args)
})

event.on('click', function(...args) {
  console.log(2, ...args)
})

event.once('click', function(...args) {
  console.log(3, ...args)
})

event.on('click', function(...args) {
  console.log(4, ...args)
})

event.emit('click', 'first').emit('click', 'second')

emit的时候,需要将数组slice出来,否则会干扰emit的时候的数组长度,导致错误。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment