一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
前言
关于异步编程一直都是面试手写题中出镜率特别高的题目,这方面的典型题目也很多,今天我们就来一起讨论一道信号灯的题目。
题目要求
用异步编程的方式实现一个信号灯(交通灯)控制器,要求:
- 红灯亮 5 秒
- 绿灯亮 6 秒
- 黄灯亮 1 秒
- 次序为 红-绿-黄-红-绿-黄
题目分析
要实现信号灯的交替显示,很容易想到使用异步来实现。
javascript 中的异步手段有哪些? 无外乎: 回调、promise
,await\async
、generator
、
基本思路:
- 红灯亮, 等待 5 秒
- 绿灯亮, 等待 6 秒
- 黄灯亮, 等待 1s
- 循环上述过程
基于这样的思路,我们先来用 Promise 来实现下
Promise 实现
class LightControl {
constructor(color, delay) {
this.color = color;
this.delay = delay;
}
start() {
return new Promise(resolve => {
console.log(this.color, "●");
setTimeout(() => {
resolve(true);
}, this.delay);
});
}
}
我们先来是实现个LightControl
类来生成一个颜色的信号灯。
start()方法返回一个promise对象,他会先打印当前颜色,然后延迟delay时间之后resolve.
我们使用这个类,一次生成三种颜色的灯。分别延迟一定的时间。
const redLight = new LightControl("red", 5000);
const greenLight = new LightControl("green", 6000);
const yellowLight = new LightControl("yellow", 1000);
紧接着我们需要写一个执行三个灯(一个循环)的方法
const executeOnce = async () => {
await redLight.start();
await greenLight.start();
await yellowLight.start();
};
executeOnce();
打印结果来看下:
这看起来不太优雅,我们用chalk
来优化下实现效果,
npm install chalk
import chalk from "chalk";
打印方式这里我们改成这样:
console.log(chalk.bold[this.color](this.color, "●"));
更多chalk的使用api可以访问其 官网
我们来看下效果:
我们再来用generator实现下:
generator实现方式
import chalk from "chalk";
function* LightControl() {
yield console.log(chalk.bold.red("●"));
yield console.log(chalk.bold.green("●"));
yield console.log(chalk.bold.yellow("●"));
}
const sleep = timeout => {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, timeout);
});
};
const runOnce = async () => {
const interator = LightControl();
interator.next();
await sleep(3000);
interator.next();
await sleep(3000);
interator.next();
await sleep(3000);
};
const executeLight = async maxTimes => {
let currentTimes = 0;
while (currentTimes < maxTimes) {
await runOnce();
currentTimes += 1;
}
};
executeLight(2);
关于generator异步的原理与实现这里就不做赘述了,可以看看我之前的这篇文章
总结
以上就是手写 信号灯 的两种异步方式实现。更文不易,欢迎点赞交流。