1. 睡眠问题

207 阅读1分钟

问题

写一个方法LazyMan,实现

const LazyManTony = new LazyMan('tony')
LazyManTony.sleep(3).eat('dinner').sleep(5).eat('junk food')

打印 3s后 -> eat dinner -> 5s后 -> junk food

问题的解答:

思路

思路.png

核心点

  1. 因为要完成链式操作,所以对应的sleep、eat要return this
  2. 因为有休眠函数和打印的顺序,有一个tasklist执行函数的队列
  3. 执行sleep、eat的函数在执行完成之后需要调用_next方法,保证后续的函数可以继续执行

代码

/**
 * 要求:实现LazyMan的链式调用,完成LazyMan(name).eat().sleep()
 * @param {name} 名字
 * @retrun {object} LazyMan 返回一个LazyManClass实例
 * @retrun {object} LazyMan.eat() 吃东西
 * @retrun {object} LazyMan.sleep() 睡多久
 * @example
 * const LazyManTony = new LazyManClass('Tony')
 * LazyManTony.eat('lunch').sleep(10).eat('dinner').sleep(20)
 */
class LazyManClass {
  constructor(name) {
    this.name = name
    this.taskList = []
    console.log(`Hi I am ${this.name}`)
    // note: 需要在完成eat/sleep方法推入之后的首次调用,触发队列的调用
    setTimeout(() => {
      this._next()
    })
  }
  _next() {
    const func = this.taskList.shift()
    func?.()
  }
  eat(food) {
    const _this = this
    const fn = function (f) {
      return function () {
        console.log(`I am eating ${f}`)
        _this._next()
      }
    }(food)
    this.taskList.push(fn)
    return this
  }
  sleep(time) {
    const _this = this
    const fn = function (t) {
      return function () {
        setTimeout(() => {
          console.log(`need sleep ${t}s`)
          _this._next()
        }, t * 1000)
      }
    }(time)
    this.taskList.push(fn)
    return this
  }
}

const LazyManTony = new LazyManClass('Tony')

LazyManTony.sleep(1).eat('lunch').sleep(2).eat('dinner').sleep(3).eat('junk food')