js实现一个 LazyMan

472 阅读1分钟

LazyMan 是一个面试中常见的面试题,它是一个模拟异步调用的函数。以下是一个实现 LazyMan 的示例代码:

class LazyManClass {
  constructor(name) {
    this.tasks = [];
    this.name = name;
    console.log(`Hi, I am ${this.name}`);
    setTimeout(() => {
      this.next();
    }, 0);
  }

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

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

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

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

function LazyMan(name) {
  return new LazyManClass(name);
}

在上述代码中,我们使用 ES6 的类来实现 LazyMan。在构造函数中,我们创建了一个 tasks 数组,用来存储需要执行的任务,并输出了一句欢迎语。然后,我们使用 setTimeout 函数来调用 next 方法,以保证构造函数执行完后才开始执行任务队列。

next 方法用于执行任务队列中的下一个任务,它从任务队列中取出第一个任务并执行。sleep 方法用于模拟睡眠功能,它会将一个延时任务添加到任务队列中。eat 方法用于模拟进食功能,它会将一个输出食物名称的任务添加到任务队列中。sleepFirst 方法用于模拟先睡眠再执行任务的功能,它会将一个延时任务添加到任务队列的头部。

最后,我们定义了一个 LazyMan 函数,用于创建 LazyManClass 类的实例。在实际使用中,我们可以通过链式调用的方式来执行任务,例如:

LazyMan('Tony')
  .eat('breakfast')
  .sleep(1000)
  .eat('lunch')
  .sleep(5000)
  .eat('dinner')
  .sleepFirst(2000);

在上述代码中,我们先创建了一个 LazyMan 对象,并使用链式调用的方式依次执行了一些任务。由于每个任务都是异步执行的,因此它们会按照预期的顺序执行。