Skip to content

Instantly share code, notes, and snippets.

@youzysu

youzysu/Cafe.js Secret

Last active February 12, 2023 15:59
Show Gist options
  • Save youzysu/8a527f22cf3aec97de7c68aacc045055 to your computer and use it in GitHub Desktop.
Save youzysu/8a527f22cf3aec97de7c68aacc045055 to your computer and use it in GitHub Desktop.
CS11. 카페 주문 이벤트

CS11. 카페 주문 이벤트

import readline from 'readline';
import { Barista } from './Barista.js';
import { CafeManager } from './CafeManager.js';
import { Cashier } from './Cashier.js';
import { DashBoard } from './DashBoard.js';
import { OrderQueue } from './OrderQueue.js';
export class Cafe {
constructor() {
this.stdio = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
this.stdio.setPrompt('> ');
this.orderQueue = new OrderQueue();
this.cashier = new Cashier(this.orderQueue);
this.barista = new Barista();
this.cafeManager = new CafeManager();
this.dashboard = new DashBoard(this.orderQueue);
}
start() {
console.log('메뉴 = 1. 아메리카노(3s) 2. 카페라떼(5s) 3. 프라프치노(10s)');
console.log('주문할 음료를 입력하세요. 예) 아메리카노 2개 => 1:2');
this.stdio.prompt();
this.stdio.on('line', (input) => this.order(input));
}
order(input) {
this.cashier.emit('readOrder', input);
}
}
import { EventEmitter } from 'events';
import { menu } from './Menu.js';
export class Cashier extends EventEmitter {
constructor(orderQueue) {
super();
this.orderQueue = orderQueue;
this.on('readOrder', (input) => setImmediate(() => this.takeOrder(input)));
}
takeOrder(input) {
const [menuKey, menuCount] = input.split(':').map(Number);
this.validate(menuKey, menuCount);
this.orderQueue.emit('order', { menuKey, menuCount });
}
validate(menuKey, menuCount) {
if (!menu.get(menuKey)) throw new Error('존재하지 않는 메뉴입니다.');
if (!menuCount) throw new Error('최소 한잔 이상 주문해야 합니다.');
}
}
import { Cafe } from './Cafe.js';
const cafe = new Cafe();
cafe.start();
class Coffee {
constructor(name, makingTime) {
this.name = name;
this.makingTime = makingTime;
}
}
const makeMenu = () => {
const menu = new Map();
menu.set(1, new Coffee('아메리카노', 3));
menu.set(2, new Coffee('카페라떼', 5));
menu.set(3, new Coffee('프라푸치노', 10));
return menu;
};
export const menu = makeMenu();
import { EventEmitter } from 'events';
export class OrderQueue extends EventEmitter {
#orders;
constructor() {
super();
this.#orders = [];
this.on('order', (order) => setImmediate(() => this.enqueue(order)));
}
enqueue(order) {
this.#orders.push(order);
}
dequeue() {
return this.#orders.shift();
}
get orders() {
return this.#orders;
}
}
{
"name": "cs11",
"version": "1.0.0",
"description": "",
"main": "main.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://gist.github.com/8a527f22cf3aec97de7c68aacc045055.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://gist.github.com/8a527f22cf3aec97de7c68aacc045055"
},
"homepage": "https://gist.github.com/8a527f22cf3aec97de7c68aacc045055"
}
// eventEmitter 동작 방식 직접 구현해보기
class myEventEmitter {
#events;
constructor() {
this.#events = {};
}
on(type, listener) {
this.#events[type] = this.#events[type] || [];
this.#events[type].push(listener);
}
emit(type) {
if (this.#events[type])
this.#events[type].forEach((listener) => listener());
}
get events() {
return this.#events;
}
}
const main = () => {
const emitter = new myEventEmitter();
emitter.on('greeting', () => console.log('Hello1~!'));
const events = emitter.events;
console.log(events);
emitter.on('greeting', () => console.log('Hello2~!'));
console.log(events);
emitter.emit('greeting');
};
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment