来,手写一个信号灯控制器!

590 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

前言

关于异步编程一直都是面试手写题中出镜率特别高的题目,这方面的典型题目也很多,今天我们就来一起讨论一道信号灯的题目。

题目要求

用异步编程的方式实现一个信号灯(交通灯)控制器,要求:

  • 红灯亮 5 秒
  • 绿灯亮 6 秒
  • 黄灯亮 1 秒
  • 次序为 红-绿-黄-红-绿-黄

题目分析

要实现信号灯的交替显示,很容易想到使用异步来实现。 javascript 中的异步手段有哪些? 无外乎: 回调、promiseawait\asyncgenerator

基本思路:

  • 红灯亮, 等待 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();

打印结果来看下:

image.png

这看起来不太优雅,我们用chalk来优化下实现效果,

npm install chalk

import chalk from "chalk"; 打印方式这里我们改成这样: console.log(chalk.bold[this.color](this.color, "●")); 更多chalk的使用api可以访问其 官网

我们来看下效果:

image.png

我们再来用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异步的原理与实现这里就不做赘述了,可以看看我之前的这篇文章

总结

以上就是手写 信号灯 的两种异步方式实现。更文不易,欢迎点赞交流。