- 面向对象信号灯设计-----源码来自 渡一教育袁老师
const serial = ['Red', 'Yellow', 'Green'];
function delay(duration = 1000) {
return new Promise(res => {
setTimeout(res, duration)
})
}
class Signal {
get next() {
return serial[(serial.indexOf(this.sig) + 1) % serial.length];
}
get remain() {
let diff = this.end - Date.now();
if (diff < 0) {
diff = 0;
}
return diff / 1000
}
constructor(options) {
this.sig = options.init;
this.times = options.times;
this.eventMap = new Map();
this.eventMap.set('change', new Set());
this.eventMap.set('tick', new Set());
this.setTime();
this.exchange();
}
on(event, handler) {
this.eventMap.get(event).add(handler)
}
off(event, handler) {
this.eventMap.get(event).delete(handler)
}
emit(event) {
this.eventMap.get(event).forEach(h => {
h.call(this, this)
});
}
async exchange() {
await 1;
if (this.remain > 0) {
this.emit('tick');
await delay(1000);
} else {
this.sig = this.next;
this.setTime();
this.emit("change");
}
this.exchange();
}
setTime() {
this.start = Date.now();
const time = this.times[serial.indexOf(this.sig)]
this.end = this.start + time * 1000;
}
}
const s = new Signal({
init: 'Red',
times: [10, 3, 5]
})
s.on('change', (e) => {
console.log(e.sig, e.next, e.remain);
})
s.on('tick', (e) => {
console.log(e.sig, e.next, e.remain);
})
s.off('tick', (e) => {
console.log(e.sig, e.next, e.remain);
})