const serial = ['Red', 'Yellow', 'Green'] //交通灯 颜色 顺序
function delay(duration = 1000) {
return new Promise(reesovle => {
setTimeout(reesovle, duration)
})
}
class Signal {
constructor(option) {
this.sig = option.init //初始化当前信号灯颜色
this.times = option.times //初始化每个信号灯颜色持续时间
this.setTime() //运行第一次 设置信号灯什么时间结束
this.exchange() //运行第一次监听
}
// 获取下一个灯 颜色
get next() {
// 此处交通灯颜色顺序数组的元素值与sig相等,所以使用indexOf函数找到此时的下标
// 得到此时下标+1,然后对交通灯颜色数量取余的值就是下一个灯的下标
// 例如 此时 是 Red 灯,在数组中下标0,物理顺序为 1,1%3取余,为1,1就是下一个灯的数组下标
let nextSig = serial[(serial.indexOf(this.sig) + 1) % serial.length]
return nextSig
}
// 获取当前灯 剩余时间
get remain() {
let diff = this.end - Date.now() // 使用提前获取的 当前灯结束时间 - 当前的系统时间 即可得到剩余时间
if (diff < 0) {
diff = 0
}
return diff / 1000
}
// 监听是否需要切换,内部自我调用,持续运行这个函数实现监听
async exchange() {
if (this.remain > 0) {
// 不需要切换
await delay(1000)
console.log(this.remain)// 打印每秒钟下的剩余时间
} else {
// 切换信号灯
this.sig = this.next
this.setTime()
console.log('信号灯切换', this.sig)
}
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
console