{ "data": { "question": { "questionId": "2797", "questionFrontendId": "2694", "categoryTitle": "JavaScript", "boundTopicId": 2265814, "title": "Event Emitter", "titleSlug": "event-emitter", "content": "
Design an EventEmitter
class. This interface is similar (but with some differences) to the one found in Node.js or the Event Target interface of the DOM. The EventEmitter
should allow for subscribing to events and emitting them.
Your EventEmitter
class should have the following two methods:
subscribe
are referentially identical.subscribe
method should also return an object with an unsubscribe
method that enables the user to unsubscribe. When it is called, the callback should be removed from the list of subscriptions and undefined
should be returned.\n
Example 1:
\n\n\nInput: actions = ["EventEmitter", "emit", "subscribe", "subscribe", "emit"], values = [[], ["firstEvent", "function cb1() { return 5; }"], ["firstEvent", "function cb1() { return 5; }"], ["firstEvent"]]\nOutput: [[],["emitted",[]],["subscribed"],["subscribed"],["emitted",[5,6]]]\nExplanation: \nconst emitter = new EventEmitter();\nemitter.emit("firstEvent"); // [], no callback are subscribed yet\nemitter.subscribe("firstEvent", function cb1() { return 5; });\nemitter.subscribe("firstEvent", function cb2() { return 6; });\nemitter.emit("firstEvent"); // [5, 6], returns the output of cb1 and cb2\n\n\n
Example 2:
\n\n\nInput: actions = ["EventEmitter", "subscribe", "emit", "emit"], values = [[], ["firstEvent", "function cb1(...args) { return args.join(','); }"], ["firstEvent", [1,2,3]], ["firstEvent", [3,4,6]]]\nOutput: [[],["subscribed"],["emitted",["1,2,3"]],["emitted",["3,4,6"]]]\nExplanation: Note that the emit method should be able to accept an OPTIONAL array of arguents.\n\nconst emitter = new EventEmitter();\nemitter.subscribe("firstEvent, function cb1(...args) { return args.join(','); });\nemitter.emit("firstEvent", [1, 2, 3]); // ["1,2,3"]\nemitter.emit("firstEvent", [3, 4, 6]); // ["3,4,6"]\n\n\n
Example 3:
\n\n\nInput: actions = ["EventEmitter", "subscribe", "emit", "unsubscribe", "emit"], values = [[], ["firstEvent", "(...args) => args.join(',')"], ["firstEvent", [1,2,3]], [0], ["firstEvent", [4,5,6]]]\nOutput: [[],["subscribed"],["emitted",["1,2,3"]],["unsubscribed",0],["emitted",[]]]\nExplanation:\nconst emitter = new EventEmitter();\nconst sub = emitter.subscribe("firstEvent", (...args) => args.join(','));\nemitter.emit("firstEvent", [1, 2, 3]); // ["1,2,3"]\nsub.unsubscribe(); // undefined\nemitter.emit("firstEvent", [4, 5, 6]); // [], there are no subscriptions\n\n\n
\n
Constraints:
\n\n1 <= actions.length <= 10
values.length === actions.length
EventEmitter
, emit
, subscribe
, and unsubscribe
.EventEmitter
action doesn't take any arguments.emit
action takes between either 1 or 2 arguments. The first argument is the name of the event we want to emit, and the 2nd argument is passed to the callback functions.subscribe
action takes 2 arguments, where the first one is the event name and the second is the callback function.unsubscribe
action takes one argument, which is the 0-indexed order of the subscription made before.设计一个 EventEmitter
类。这个接口与 Node.js 或 DOM 的 Event Target 接口相似,但有一些差异。EventEmitter
应该允许订阅事件和触发事件。
你的 EventEmitter
类应该有以下两个方法:
subscribe
的回调函数都不是引用相同的。 subscribe
方法还应返回一个对象,其中包含一个 unsubscribe
方法,使用户可以取消订阅。当调用 unsubscribe
方法时,回调函数应该从订阅列表中删除,并返回 undefined。\n\n
示例 1:
\n\n\n输入:actions = [\"EventEmitter\", \"emit\", \"subscribe\", \"subscribe\", \"emit\"], values = [[], [\"firstEvent\", \"function cb1() { return 5; }\"], [\"firstEvent\", \"function cb1() { return 5; }\"], [\"firstEvent\"]]\n输出:[[],[\"emitted\",[]],[\"subscribed\"],[\"subscribed\"],[\"emitted\",[5,6]]]\n解释:\nconst emitter = new EventEmitter();\nemitter.emit(\"firstEvent\"); // [], 还没有订阅任何回调函数\nemitter.subscribe(\"firstEvent\", function cb1() { return 5; });\nemitter.subscribe(\"firstEvent\", function cb2() { return 6; });\nemitter.emit(\"firstEvent\"); // [5, 6], 返回 cb1 和 cb2 的输出\n\n\n
示例 2:
\n\n\n输入:actions = [\"EventEmitter\", \"subscribe\", \"emit\", \"emit\"], values = [[], [\"firstEvent\", \"function cb1(...args) { return args.join(','); }\"], [\"firstEvent\", [1,2,3]], [\"firstEvent\", [3,4,6]]]\n输出:[[],[\"subscribed\"],[\"emitted\",[\"1,2,3\"]],[\"emitted\",[\"3,4,6\"]]]\n解释:注意 emit 方法应该能够接受一个可选的参数数组。\n\nconst emitter = new EventEmitter();\nemitter.subscribe(\"firstEvent, function cb1(...args) { return args.join(','); });\nemitter.emit(\"firstEvent\", [1, 2, 3]); // [\"1,2,3\"]\nemitter.emit(\"firstEvent\", [3, 4, 6]); // [\"3,4,6\"]\n\n\n
示例 3:
\n\n\n输入:actions = [\"EventEmitter\", \"subscribe\", \"emit\", \"unsubscribe\", \"emit\"], values = [[], [\"firstEvent\", \"(...args) => args.join(',')\"], [\"firstEvent\", [1,2,3]], [0], [\"firstEvent\", [4,5,6]]]\n输出:[[],[\"subscribed\"],[\"emitted\",[\"1,2,3\"]],[\"unsubscribed\",0],[\"emitted\",[]]]\n解释:\nconst emitter = new EventEmitter();\nconst sub = emitter.subscribe(\"firstEvent\", (...args) => args.join(','));\nemitter.emit(\"firstEvent\", [1, 2, 3]); // [\"1,2,3\"]\nsub.unsubscribe(); // undefined\nemitter.emit(\"firstEvent\", [4, 5, 6]); // [], 没有订阅者\n\n\n
\n\n
提示:
\n\n1 <= actions.length <= 10
values.length === actions.length
EventEmitter
、emit
、subscribe
和 unsubscribe
。 EventEmitter
操作没有参数。emit
操作接收 1 或 2 个参数。第一个参数是要触发的事件名,第二个参数传递给回调函数。subscribe
操作接收 2 个参数,第一个是事件名,第二个是回调函数。unsubscribe
操作接收一个参数,即之前进行订阅的顺序(从 0 开始)。\\u7248\\u672c\\uff1a \\u60a8\\u7684\\u4ee3\\u7801\\u5728\\u6267\\u884c\\u65f6\\u5c06\\u5e26\\u4e0a lodash.js<\\/a> \\u5e93\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5305\\u542b\\u3002<\\/p>\\r\\n\\r\\n \\u5982\\u9700\\u4f7f\\u7528\\u961f\\u5217\\/\\u4f18\\u5148\\u961f\\u5217\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 datastructures-js\\/priority-queue@5.3.0<\\/a> \\u548c datastructures-js\\/queue@4.2.1<\\/a>\\u3002<\\/p>\"],\"typescript\":[\"TypeScript\",\" TypeScript 4.5.4<\\/p>\\r\\n\\r\\n Compile Options: --alwaysStrict --strictBindCallApply --strictFunctionTypes --target ES2020<\\/p>\\r\\n\\r\\n lodash.js<\\/a> \\u5e93\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5305\\u542b\\u3002<\\/p>\\r\\n\\r\\n \\u5982\\u9700\\u4f7f\\u7528\\u961f\\u5217\\/\\u4f18\\u5148\\u961f\\u5217\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 datastructures-js\\/priority-queue@5.3.0<\\/a> \\u548c datastructures-js\\/queue@4.2.1<\\/a>\\u3002<\\/p>\"]}",
"book": null,
"isSubscribed": false,
"isDailyQuestion": false,
"dailyRecordStatus": null,
"editorType": "CKEDITOR",
"ugcQuestionId": null,
"style": "LEETCODE",
"exampleTestcases": "[\"EventEmitter\", \"emit\", \"subscribe\", \"subscribe\", \"emit\"]\n[[], [\"firstEvent\"], [\"firstEvent\", \"function cb1() { return 5; }\"], [\"firstEvent\", \"function cb1() { return 6; }\"], [\"firstEvent\"]]\n[\"EventEmitter\", \"subscribe\", \"emit\", \"emit\"]\n[[], [\"firstEvent\", \"function cb1(...args) { return args.join(','); }\"], [\"firstEvent\", [1,2,3]], [\"firstEvent\", [3,4,6]]]\n[\"EventEmitter\", \"subscribe\", \"emit\", \"unsubscribe\", \"emit\"]\n[[], [\"firstEvent\", \"(...args) => args.join(',')\"], [\"firstEvent\", [1,2,3]], [0], [\"firstEvent\", [4,5,6]]]",
"__typename": "QuestionNode"
}
}
}Node.js 16.13.2<\\/code><\\/p>\\r\\n\\r\\n
--harmony<\\/code> \\u6807\\u8bb0\\u6765\\u5f00\\u542f \\u65b0\\u7248ES6\\u7279\\u6027<\\/a>\\u3002<\\/p>\\r\\n\\r\\n