发布订阅类01

42 阅读1分钟

tiny-emitter/index.js at master · scottcorgan/tiny-emitter · GitHub

JavaScript发布订阅类

留个纪录哈哈......

class E {
  e = {}
  on(name, cb, ctx) {
    (this.e[name] || (this.e[name] = [])).push({
      callback: cb,
      ctx
    })
    return this
  }
  once(name, cb, ctx) {

    const _cb = (...args) => {
      this.off(name, cb)
      cb.apply(ctx, args)
    }
    _cb._cb = cb
    return this.on(name, _cb, ctx)
  }
  off(name, cb) {
    if (!name) return this
    if (!cb) {
      delete this.e[name]
      return this
    }
    let liveEvents = []
    this.e[name]?.forEach(({callback, ctx}) => {
      if (!(callback === cb || callback._cb === cb)) {
        liveEvents.push({callback, ctx})
      }
    })
    liveEvents.length ? (this.e[name] = liveEvents) : (delete this.e[name])
    return this
  }
  emit(name, ...args) {
    // console.log(this.e[name])
    this.e[name]?.forEach(({callback, ctx}) => {
      callback.apply(ctx, args)
    })
    return this
  }
}

const emitter = new E()
// on
function foo() {
  console.log('foo -- this arguments', this, arguments)
}
function bar() {
  console.log('bar -- this arguments', this, arguments)
}
// emitter.on('foo-test', foo, { name: 'nct' })
// emitter.on('foo-test', bar, { name: 'ctx' })
// emitter.emit('foo-test')
// emitter.emit('foo-test', 66, {hello: 'world'})

// once
// emitter.once('bar-test', bar, { age: 18 })
// emitter.emit('bar-test', true, 'haha')
// emitter.emit('bar-test', false, 'xixi')

// off
// emitter.on('foo', foo, { name: 'foo' }).on('foo', bar, { name: 'bar' }).emit('foo', 'xiha').off('foo', foo).emit('foo', 'gg')
// emitter.on('foo', foo, { name: 'foo' }).on('foo', bar, { name: 'bar' }).emit('foo', 'xiha').off('foo').emit('foo', 'gg')
// emitter.on('foo', foo, { name: 'foo' }).once('foo', bar, { name: 'bar' }).emit('foo', 'xiha').off('foo', foo).emit('foo', 'gg')
emitter.on('foo', foo, { name: 'foo' }).once('foo', bar, { name: 'bar' }).emit('foo', 'xiha').off('foo', bar).emit('foo', 'gg')