TrafficLight

用js实现红绿灯效果:红 4s -> 黄 2s -> 绿 4s -> 黄 2s 循环播放

// 初始化红绿灯集合
const lights = [
  {
    name: '红',
    time: 4000,
  },
  {
    name: '黄',
    time: 2000,
  },
  {
    name: '绿',
    time: 4000,
  },
]

// 初始化指针
const point = {
  position: 0,
  direction: 0, // 控制指针移动方向属性:0:向右,1:向左
}

recycle()

/**
 * 指针移动控制器
 * 通过判断指针位置控制指针移动方向
 */
function recycle() {
  activeLights(lights[point.position])
  if (point.position < lights.length - 1 && point.direction === 0) {
    // 如果指针未到达最后一个元素并且指针移动方向向右,则执行右向下一个任务
    point.position += 1
  } else if (point.position > 0 && point.direction === 1) {
    // 如果指针未到达第一个元素并且指针移动方向向左,则执行左向下一个任务
    point.position -= 1
  } else if (point.position === lights.length - 1) {
    // 如果指针位置在最后一个元素,则改变方向向左
    point.direction = 1
    point.position -= 1
  } else if (point.position === 0) {
    // 如果指针位置在第一个元素,则改变方向向右
    point.direction = 0
    point.position += 1
  }
}

/**
 * 激活指定灯的闪烁
 */
function activeLights(light) {
  class TwinkleLight {
    constructor() {
      this.light = light
      this.count = 0
    }

    twinkle() {
      const that = this
      const promise = new Promise(((resolve) => {
        setTimeout(function () {
          console.log(`${that.light.name} - ${that.count + 1}`)
          that.count += 1
          if (that.count === that.light.time / 1000) {
            resolve(that.count)
          } else {
            that.twinkle()
          }
        }, 1000)
      }))
      // 成功回调后才执行下一次闪烁
      promise.then(() => {
        recycle()
        return true
      }).catch((err) => {
        console.warn(`Error: ${err}`)
      })
    }
  }

  const twinkle = new TwinkleLight(light)
  twinkle.twinkle()
}

Last updated