返回

前端流程控制面试题:构建一个LazyMan类

前端

刚开始拿到题目的时候还是比较懵的,无从下手,不过为了offer还是很快的静下心来去分析题目。

首先,题目要求我们构建一个LazyMan类,并且提供若干个方法来控制程序流程。

题目给的例子比较明确:

  • sleep(1000, function(){...}) 等待1000毫秒后执行函数
  • eat(function(){...}) 吃
  • sleepFirst(1000, function(){...}) 先睡觉1000毫秒,再执行函数

从这个例子可以看出,LazyMan类应该是一个可以控制程序流程的类,并且可以链式调用。

于是我首先定义了LazyMan类:

class LazyMan {
  constructor(name) {
    this.tasks = [];
    this.name = name;
    setTimeout(() => {
      this.next();
    }, 0);
  }

  next() {
    const task = this.tasks.shift();
    if (task) {
      task();
    }
  }

  sleep(time, callback) {
    const task = () => {
      setTimeout(() => {
        console.log(`Wake up after ${time}ms`);
        callback && callback();
        this.next();
      }, time);
    };
    this.tasks.push(task);
    return this;
  }

  eat(callback) {
    const task = () => {
      console.log(`Eat something...`);
      callback && callback();
      this.next();
    };
    this.tasks.push(task);
    return this;
  }

  sleepFirst(time, callback) {
    const task = () => {
      setTimeout(() => {
        console.log(`Wake up after ${time}ms`);
        callback && callback();
        this.next();
      }, time);
    };
    this.tasks.unshift(task);
    return this;
  }
}

这个类定义了一个name属性来存储LazyMan的名称,以及一个tasks数组来存储任务。

next方法用于执行下一个任务,如果tasks数组不为空,则取出第一个任务并执行。

sleep方法用于创建一个新的任务,该任务会在指定时间后执行。

eat方法用于创建一个新的任务,该任务会立即执行。

sleepFirst方法用于创建一个新的任务,该任务会在所有其他任务之前执行。

现在,我们可以使用这个LazyMan类来实现题目的要求:

const lazyMan = new LazyMan('Hank')

lazyMan.eat(() => {
  console.log(`Eat something...`)
}).sleep(1000, () => {
  console.log(`Wake up after 1000ms`)
}).sleepFirst(500, () => {
  console.log(`Wake up after 500ms`)
}).eat(() => {
  console.log(`Eat something...`)
})

这段代码会输出:

Eat something...
Wake up after 500ms
Wake up after 1000ms
Eat something...

这正是题目要求的结果。

希望这篇文章对您有所帮助。如果您有任何问题,请随时留言。