列表

详情


2694. 事件发射器

设计一个 EventEmitter 类。这个接口与 Node.js 或 DOM 的 Event Target 接口相似,但有一些差异。EventEmitter 应该允许订阅事件和触发事件。

你的 EventEmitter 类应该有以下两个方法:

 

示例 1:

输入:actions = ["EventEmitter", "emit", "subscribe", "subscribe", "emit"], values = [[], ["firstEvent", "function cb1() { return 5; }"],  ["firstEvent", "function cb1() { return 5; }"], ["firstEvent"]]
输出:[[],["emitted",[]],["subscribed"],["subscribed"],["emitted",[5,6]]]
解释:
const emitter = new EventEmitter();
emitter.emit("firstEvent"); // [], 还没有订阅任何回调函数
emitter.subscribe("firstEvent", function cb1() { return 5; });
emitter.subscribe("firstEvent", function cb2() { return 6; });
emitter.emit("firstEvent"); // [5, 6], 返回 cb1 和 cb2 的输出

示例 2:

输入:actions = ["EventEmitter", "subscribe", "emit", "emit"], values = [[], ["firstEvent", "function cb1(...args) { return args.join(','); }"], ["firstEvent", [1,2,3]], ["firstEvent", [3,4,6]]]
输出:[[],["subscribed"],["emitted",["1,2,3"]],["emitted",["3,4,6"]]]
解释:注意 emit 方法应该能够接受一个可选的参数数组。

const emitter = new EventEmitter();
emitter.subscribe("firstEvent, function cb1(...args) { return args.join(','); });
emitter.emit("firstEvent", [1, 2, 3]); // ["1,2,3"]
emitter.emit("firstEvent", [3, 4, 6]); // ["3,4,6"]

示例 3:

输入:actions = ["EventEmitter", "subscribe", "emit", "unsubscribe", "emit"], values = [[], ["firstEvent", "(...args) => args.join(',')"], ["firstEvent", [1,2,3]], [0], ["firstEvent", [4,5,6]]]
输出:[[],["subscribed"],["emitted",["1,2,3"]],["unsubscribed",0],["emitted",[]]]
解释:
const emitter = new EventEmitter();
const sub = emitter.subscribe("firstEvent", (...args) => args.join(','));
emitter.emit("firstEvent", [1, 2, 3]); // ["1,2,3"]
sub.unsubscribe(); // undefined
emitter.emit("firstEvent", [4, 5, 6]); // [], 没有订阅者

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class EventEmitter { subscribe(event, cb) { return { unsubscribe: () => { } }; } emit(event, args = []) { } } /** * const emitter = new EventEmitter(); * * // Subscribe to the onClick event with onClickCallback * function onClickCallback() { return 99 } * const sub = emitter.subscribe('onClick', onClickCallback); * * emitter.emit('onClick'); // [99] * sub.unsubscribe(); // undefined * emitter.emit('onClick'); // [] */

javascript 解法, 执行用时: 80 ms, 内存消耗: 41.6 MB, 提交时间: 2023-05-22 14:29:18

class EventEmitter {
  constructor() {
    this.ke = {}
  }
  subscribe(event, cb) {
    if(!this.ke[event])  this.ke[event] = []
    this.ke[event].push(cb)
    return {
        unsubscribe: () => {
            this.ke[event] = this.ke[event].filter(v => v !== cb)   
        }
    };
  }
  
  emit(event, args = []) {
     return (this.ke[event] ?? []).map(v => v(...args))
  }
}

/**
 * const emitter = new EventEmitter();
 *
 * // Subscribe to the onClick event with onClickCallback
 * function onClickCallback() { return 99 }
 * const sub = emitter.subscribe('onClick', onClickCallback);
 *
 * emitter.emit('onClick'); // [99]
 * sub.unsubscribe(); // undefined
 * emitter.emit('onClick'); // []
 */

typescript 解法, 执行用时: 60 ms, 内存消耗: 44 MB, 提交时间: 2023-05-22 14:24:39

type Callback = (...args: any[]) => any;
type Subscription = {
    unsubscribe: () => void
}

class EventEmitter {
  #eventsMap: Map<string, Set<Callback>> = new Map();
  subscribe(eventName: string, callback: Callback): Subscription {
    this.#eventsMap.set(eventName, (this.#eventsMap.get(eventName)??new Set()).add(callback));
    return {
      unsubscribe: () => {
        this.#eventsMap.get(eventName)?.delete(callback);
      }
    };
  }

  emit(eventName: string, args: any[] = []): any {
    return [...(this.#eventsMap.get(eventName)??[])].map(fn=>fn?.(...args));
  }
}

/**
 * const emitter = new EventEmitter();
 *
 * // Subscribe to the onClick event with onClickCallback
 * function onClickCallback() { return 99 }
 * const sub = emitter.subscribe('onClick', onClickCallback);
 *
 * emitter.emit('onClick'); // [99]
 * sub.unsubscribe(); // undefined
 * emitter.emit('onClick'); // []
 */

/**
 * const emitter = new EventEmitter();
 *
 * // Subscribe to the onClick event with onClickCallback
 * function onClickCallback() { return 99 }
 * const sub = emitter.subscribe('onClick', onClickCallback);
 *
 * emitter.emit('onClick'); // [99]
 * sub.unsubscribe(); // undefined
 * emitter.emit('onClick'); // []
 */

上一题