Promise - 实现红黄绿灯交替闪烁

843 阅读2分钟

Promise 作为异步编程一个的解决方案,在面试中经常会被问到,下面我们就来做一道代码题来检验一下我们的掌握程度。

题目描述:使用 Promise 实现红绿灯,红灯 3秒亮一次,黄灯 2秒亮一次,绿灯 1秒亮一次。如何使用 Promise 让三个灯不间断交替重复亮,其中,红黄绿灯的方法已经提供。

function red() {
  console.log('红灯亮');
}
function yellow() {
  console.log('黄灯亮');
}
function green() {
  console.log('绿灯亮');
}

下面有两种解决方案:

1. Promise

首先,我们可以使用 setTimeout 实现三个灯几秒亮一次

function light(callback, timer) {
    setTimeout(() => {
        callback && callback();
    }, timmer);
}

然后,我们可以使用 promise 的then函数的链式调用来实现红绿灯交替亮,而且我们还要满足红灯亮完黄灯亮,黄灯亮完绿灯亮,所以 then 函数需要 return 一个结果或者 Promise 对象,在状态改变之后,再执行之后的 then 函数

function light(callback, timer) {
    return new Promise(resolve => {
        setTimeout(() => {
            callback && callback();
            resolve();
        }, timer);
    })
}

function lightStep() {
    Promise().resolve().then(() => {
        return light(red, 3000);
    }).then(() => {
        return light(yellow, 2000);
    }).then(() => {
        return light(green, 1000);
    });
}

最后,我们需要使用 promise 的 finally 函数实现三个灯不间断重复交替亮。我们看一下最终的完整代码。

function light(callback, timer) {
    return new Promise(resolve => {
        setTimeout(() => {
            callback && callback();
            resolve();
        }, timer);
    })
}

function lightStep() {
    Promise.resolve().then(() => {
        return light(red, 3000);
    }).then(() => {
        return light(yellow, 2000);
    }).then(() => {
        return light(green, 1000);
    }).finally(() => {
        return lightStep();
    });
}

2. async / await

使用 async / await 这种方式,我们需要知道:

  • async 返回一个 Promise 对象
  • await 后面如果是一个 promise 对象,则需要等待这个 promise 返回结果,所以此时后续的代码相当于 Promise 的 then;如果await 后面是一个普通的 js 函数,则直接执行后续的代码
async function lightStep() {
    await light(red, 3000);
    await light(yellow, 2000);
    await light(green, 1000);
    await lightStep();
}

如有问题,欢迎批评指正~⛷️