Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
</body>
</html>
 
class EventHub {
  constructor() {
    // 调度中心
    this.channel = {}
  }
  on(name, fn) {
    this.channel[name] = this.channel[name] || []
    this.channel[name].push(fn)
  }
  off(name, fn) {
    const list = this.channel[name] || []
    const index = list.indexOf(fn)
    if(index < 0) return
    list.splice(index, 1)
  }
  once(name, fn) {
    this.channel[name] = this.channel[name] || []
    let one = (arg) => {
      fn.call(null, arg)
    }
    // 记录下绑定事件
    one.fn = fn
    // 添加移除方法
    one.off = () => { this.off(name, one) }
    this.on(name, one)
  }
  emit(name, data) {
    let list = this.channel[name] || []
    let ones = []
    list.forEach(fn => {
      fn.call(null, data)
      fn.off && ones.push(fn)
    })
    // 移除once订阅事件、执行完再移除不会导致删除数组后执行顺序不对问题
    ones.forEach(fn => fn.off())
  }
}
let q = new EventHub()
q.on('click', function(data) {
  console.log('on')
})
q.once('click', function(data) {
  console.log('once')
})
q.emit('click')
q.emit('click')
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers