lazyMan实现

题目大概是实现一个如下功能的程序:

LazyMan(‘tom’)
输出:
“this is tom”
LazyMan(‘tom’).sleep(10).eat(‘apple’)
输出:
“this is tom”
等待10秒…
“eat apple”
LazyMan(‘tom’).eat(‘apple’).eat(‘banana’)
输出:
“this is tom”
“eat apple”
“eat banana”
LazyMan(‘tom’).eat(‘banana’).sleepFirst(5)
输出:
等待 5 秒…
“this is tom”
“eat banana”

分析

从输出结果看有几个特点:

  • 链式调用,可以一直调用下去。一般会有两种方式实现:队列&promise。
  • 任务有两种,一种输出顺序和调用位置一致,另一种是sleepFirst。后调用却先输出。所以这里更适合采用队列来实现,根据任务类型来判断是添加在队尾还是队首。
  • 基于以上分析可知,每次调用函数只是向队列添加任务而已。执行任务在下一个时机。 可以考虑使用setTimeout来实现。

代码实现

class _LazyMan {
     
  constructor(name) {
     
    this.name = name;
    this.tasks = [this.sayName];  //任务队列 默认添加sayName在队列中
    setTimeout(() => this.next(), 0)  // 任务添加完毕后,下一个宏任务中执行队列
  }

  /**
   * 添加任务
   * @param {function} task  任务
   * @param {boolean} addToTail 添加在队尾
   */
  addTask(task, addToTail = true) {
     
    if (addToTail) {
     
      this.tasks.push(task)
    } else {
     
      this.tasks.unshift(task)
    }
  }

  //每次去任务队列的第一个任务执行
  next = () => {
     
    const task = this.tasks.shift()
    task && task()
  }

  sayName = () => {
     
    console.log(`this is ${
       this.name}`)
    this.next()
  }
  eat = (name) => {
     
    this.addTask(() => {
     
      console.log(`eat ${
       name}`)
      this.next()
    })
    return this     // 必须return this 方便链式调用,继续向队列添加任务
  }

  sleep = (time) => {
     
    this.addTask(this.sleepTask(time))
    return this
  }

  sleepFirst = (time) => {
     
    this.addTask(this.sleepTask(time), false)
    return this
  }

  sleepTask = (time) => {
     
    return () => {
     
      console.log(`等待${
       time}秒 ...`)
      setTimeout((() => {
     
        this.next()
      }), time * 1000)
    }
  }
}

function LazyMan(name) {
     
  return new _LazyMan(name)
}

查看更多内容请点击这里

参考文档:

lazyMan

你可能感兴趣的:(题目练习,数据结构,js,javascript)