{ "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.

\n\n

Your EventEmitter class should have the following two methods:

\n\n\n\n

 

\n

Example 1:

\n\n
\nInput: \nactions = ["EventEmitter", "emit", "subscribe", "subscribe", "emit"], \nvalues = [[], ["firstEvent", "function cb1() { return 5; }"],  ["firstEvent", "function cb1() { return 6; }"], ["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: \nactions = ["EventEmitter", "subscribe", "emit", "emit"], \nvalues = [[], ["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 arguments.\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: \nactions = ["EventEmitter", "subscribe", "emit", "unsubscribe", "emit"], \nvalues = [[], ["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

Example 4:

\n\n
\nInput: \nactions = ["EventEmitter", "subscribe", "subscribe", "unsubscribe", "emit"], \nvalues = [[], ["firstEvent", "x => x + 1"], ["firstEvent", "x => x + 2"], [0], ["firstEvent", [5]]]\nOutput: [[],["subscribed"],["emitted",["1,2,3"]],["unsubscribed",0],["emitted",[7]]]\nExplanation:\nconst emitter = new EventEmitter();\nconst sub1 = emitter.subscribe("firstEvent", x => x + 1);\nconst sub2 = emitter.subscribe("firstEvent", x => x + 2);\nsub1.unsubscribe(); // undefined\nemitter.emit("firstEvent", [5]); // [7]
\n\n

 

\n

Constraints:

\n\n\n", "translatedTitle": "事件发射器", "translatedContent": "

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

\n\n

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

\n\n\n\n

 

\n\n

示例 1:

\n\n
\n输入:\nactions = [\"EventEmitter\", \"emit\", \"subscribe\", \"subscribe\", \"emit\"], \nvalues = [[], [\"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输入:\nactions = [\"EventEmitter\", \"subscribe\", \"emit\", \"emit\"], \nvalues = [[], [\"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输入:\nactions = [\"EventEmitter\", \"subscribe\", \"emit\", \"unsubscribe\", \"emit\"], \nvalues = [[], [\"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

示例 4:

\n\n
\n输入:\nactions = [\"EventEmitter\", \"subscribe\", \"subscribe\", \"unsubscribe\", \"emit\"], \nvalues = [[], [\"firstEvent\", \"x => x + 1\"], [\"firstEvent\", \"x => x + 2\"], [0], [\"firstEvent\", [5]]]\n输出:[[],[\"subscribed\"],[\"emitted\",[\"1,2,3\"]],[\"unsubscribed\",0],[\"emitted\",[7]]]\n解释:\nconst emitter = new EventEmitter();\nconst sub1 = emitter.subscribe(\"firstEvent\", x => x + 1);\nconst sub2 = emitter.subscribe(\"firstEvent\", x => x + 2);\nsub1.unsubscribe(); // undefined\nemitter.emit(\"firstEvent\", [5]); // [7]
\n\n

 

\n\n

提示:

\n\n\n", "isPaidOnly": false, "difficulty": "Medium", "likes": 5, "dislikes": 0, "isLiked": null, "similarQuestions": "[]", "contributors": [], "langToValidPlayground": "{\"cpp\": false, \"java\": true, \"python\": true, \"python3\": false, \"mysql\": false, \"mssql\": false, \"oraclesql\": false, \"c\": false, \"csharp\": false, \"javascript\": false, \"typescript\": false, \"bash\": false, \"php\": false, \"swift\": false, \"kotlin\": false, \"dart\": false, \"golang\": false, \"ruby\": false, \"scala\": false, \"html\": false, \"pythonml\": false, \"rust\": false, \"racket\": false, \"erlang\": false, \"elixir\": false, \"pythondata\": false, \"react\": false, \"vanillajs\": false, \"postgresql\": false}", "topicTags": [], "companyTagStats": null, "codeSnippets": [ { "lang": "JavaScript", "langSlug": "javascript", "code": "class EventEmitter {\n \n /**\n * @param {string} eventName\n * @param {Function} callback\n * @return {Object}\n */\n\tsubscribe(eventName, callback) {\n \t\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\t\n\t\t\t}\n\t\t};\n\t}\n \n /**\n * @param {string} eventName\n * @param {Array} args\n * @return {Array}\n */\n\temit(eventName, args = []) {\n\t\t\n\t}\n}\n\n/**\n * const emitter = new EventEmitter();\n *\n * // Subscribe to the onClick event with onClickCallback\n * function onClickCallback() { return 99 }\n * const sub = emitter.subscribe('onClick', onClickCallback);\n *\n * emitter.emit('onClick'); // [99]\n * sub.unsubscribe(); // undefined\n * emitter.emit('onClick'); // []\n */", "__typename": "CodeSnippetNode" }, { "lang": "TypeScript", "langSlug": "typescript", "code": "type Callback = (...args: any[]) => any;\ntype Subscription = {\n unsubscribe: () => void\n}\n\nclass EventEmitter {\n \n\tsubscribe(eventName: string, callback: Callback): Subscription {\n\t\t\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\t\n\t\t\t}\n };\n\t}\n\n\temit(eventName: string, args: any[] = []): any[] {\n\t\t\n\t}\n}\n\n/**\n * const emitter = new EventEmitter();\n *\n * // Subscribe to the onClick event with onClickCallback\n * function onClickCallback() { return 99 }\n * const sub = emitter.subscribe('onClick', onClickCallback);\n *\n * emitter.emit('onClick'); // [99]\n * sub.unsubscribe(); // undefined\n * emitter.emit('onClick'); // []\n */", "__typename": "CodeSnippetNode" } ], "stats": "{\"totalAccepted\": \"1.6K\", \"totalSubmission\": \"2.5K\", \"totalAcceptedRaw\": 1635, \"totalSubmissionRaw\": 2502, \"acRate\": \"65.3%\"}", "hints": [], "solution": null, "status": null, "sampleTestCase": "[\"EventEmitter\", \"emit\", \"subscribe\", \"subscribe\", \"emit\"]\n[[], [\"firstEvent\"], [\"firstEvent\", \"function cb1() { return 5; }\"], [\"firstEvent\", \"function cb1() { return 6; }\"], [\"firstEvent\"]]", "metaData": "{\n \"name\": \"EventEmitter\",\n \"params\": [\n {\n \"type\": \"string[]\",\n \"name\": \"actions\"\n },\n {\n \"type\": \"character[][]\",\n \"name\": \"values\"\n }\n ],\n \"return\": {\n \"type\": \"void\"\n },\n \"languages\": [\n \"typescript\",\n \"javascript\"\n ],\n \"manual\": true\n}", "judgerAvailable": true, "judgeType": "large", "mysqlSchemas": [], "enableRunCode": true, "envInfo": "{\"javascript\":[\"JavaScript\",\"

\\u7248\\u672c\\uff1aNode.js 16.13.2<\\/code><\\/p>\\r\\n\\r\\n

\\u60a8\\u7684\\u4ee3\\u7801\\u5728\\u6267\\u884c\\u65f6\\u5c06\\u5e26\\u4e0a --harmony<\\/code> \\u6807\\u8bb0\\u6765\\u5f00\\u542f \\u65b0\\u7248ES6\\u7279\\u6027<\\/a>\\u3002<\\/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>\"],\"typescript\":[\"TypeScript\",\"

TypeScript 5.1.6<\\/p>\\r\\n\\r\\n

Compile Options: --alwaysStrict --strictBindCallApply --strictFunctionTypes --target ES2022<\\/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]]]\n[\"EventEmitter\", \"subscribe\", \"subscribe\", \"unsubscribe\", \"emit\"]\n[[], [\"firstEvent\", \"x => x + 1\"], [\"firstEvent\", \"x => x + 2\"], [0], [\"firstEvent\", [5]]]", "__typename": "QuestionNode" } } }