const serial = ['Red','Yellow','Green']
/*
* @author miao 2023-01-29
* @param duration {number} 延迟的时间
* @return {Promise} 返回Promise
* @example delay(1000)
*/
function delay(duration = 1000) {
return new Promise(resolve => {
setTimeout(resolve,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('trck', new Set())
this.setTime();
this.exchange();
}
on(event, handle) {
this.eventMap.get(event).add(handle)
}
off(event, handle) {
this.eventMap.get(event).delete(handle)
}
emit(event) {
this.eventMap.get(event).forEach(h => {
h.call(this,this);
});
}
async exchange() {
await 1;
if(this.remain > 0) {
this.emit('trck')
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:'Green',
times:[10,3,5]
})
function handle(params) {
console.log(params.sig, Math.round(params.remain))
}
s.on('trck',handle)
setTimeout(()=>{
s.off('trck',handle)
},15000)