【编程题】红灯亮三秒,绿灯一秒 黄灯两秒 交替进行

今天舍友面试前端岗位,分享了面经,其中有道编程题:
红灯三秒亮一次,绿灯一秒亮一次,黄灯两秒亮一次,如何让三个灯不断交替重复亮灯?
复制代码

涉及到时间,那应该就需要用到setTimeout方法,我们可以让程序三秒后打印红灯,一秒后打印绿灯,两秒后打印黄灯

    const red = () => {
        setTimeout(() => {
            console.log('red');
        },3000)
    }
    const green = () => {
        setTimeout(() => {
            console.log('green');
        },1000)
    }
    const yellow = () => {
        setTimeout(() => {
            console.log('yellow');
        },2000)
    }
    red();
    green();
    yellow();
复制代码

直接执行这三个方法会发现,不是按照3秒后打印出red再过1秒打印出green再过2秒打印yellow
这是因为setTimeout是异步调用回调的,当执行setTimeout方法,会把回调放到事件队列中,主线程继续执行下面的代码。

那么有什么办法可以等待异步执行完再执行接下去的代码呢?
答案是Async/Await
我们把代码改造一下:

let time = null;
const red = () => {
  const now = Date.now();
  console.log('red', Math.floor((now - time)/1000));
  time = Date.now();
}
const yellow = () => {
  const now = Date.now();
  console.log('yellow', Math.floor((now - time)/1000));
  time = Date.now();
}
const green = () => {
  const now = Date.now();
  console.log('green', Math.floor((now - time)/1000));
  time = Date.now();
}
const light = (time, callback) => {
  return new Promise((res, rej) => {
    const timer = setTimeout(() => {
      callback();
      res(timer);
    }, time);
  })
}
const stepByStep = async () => {
  const timer1 = await light(3000, red);
  const timer2 = await light(1000, green);
  const timer3 = await light(2000, yellow);
  clearTimeout(timer1);
  clearTimeout(timer2);
  clearTimeout(timer3);
}
time = Date.now();
stepByStep();
复制代码

light方法中,返回一个Promise实例,这个promisesetTimeout回调执行时才进行resolve将状态转为完成态,所以可以利用await的特性:强制等待Promise完成再继续执行其他代码。

最后,如何循环让其交替亮灯呢?

const stepByStep = async () => {
  const timer1 = await light(3000, red);
  const timer2 = await light(1000, green);
  const timer3 = await light(2000, yellow);
  clearTimeout(timer1);
  clearTimeout(timer2);
  clearTimeout(timer3);
  # 递归调用就可以
  stepByStep();
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享