面试题——设计一个lazyman类

155 阅读1分钟

用两种方法实现下:

  1. 创建类,定义一个回调队列,链式调用它
  2. 用promise搭配await

// 设计一个LazyMan类,实现以下功能
LazyMan('Tony')
// Hi I am Tony
LazyMan('Tony').sleep(10).eat('lunch')
// Hi I am Tony
// 等待10秒...
// I am eating lunch
LazyMan('Tony').eat('lunch').sleep(10).eat('dinner')
// Hi I am Tony
// I am eating lunch
// 等待10秒...
// I am eating dinner
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food')
// Hi I am Tony
// 等待了5秒...
// I am eating lunch
// I am eating dinner
// 等待10秒
// I am eating junk food

用类实现如下

  class lazyMan {
    constructor (name) {
      this.name = name
      this.callback = []
      console.log(`i'm ${this.name}`)
      setTimeout(() => {
        this.next()
      }, 0)
    }
    // 先定义链式调用
    next () {
      const fn = this.callback.shift()
      fn && fn()
    }

    sleep(s){
      const timer =(()=>{
        setTimeout(() => {
          console.log(`等待了${s}秒...`)
          this.next()
        },s*1000)
        
      }) 
      this.callback.push(timer)
      return this
    }
    firstSleep(s){
      const timer =(()=>{
        setTimeout(() => {
          console.log(`等待了${s}秒...`)
          this.next()
        },s*1000)
        
      }) 
      this.callback.unshift(timer)
      return this
    }
    eat(food) {
      const fn = () => {
        console.log(`I am eating ${food}`)
        this.next()
      }
      this.callback.push(fn)
      return this
    }
  }
  new lazyMan('tom').sleep(3).eat('apple').firstSleep(2)

用promise实现,也是一种途径

{
  const lazyMan = (name) => {
    return new Promise((resolve, reject) => {
      console.log(`i'm ${name}`)
      resolve()
    })
  }
  const sleep = (s) => {
    return new Promise((resolve, reject) => {
      setTimeout(()=>{
        console.log(`等待了${s}秒...`)
        resolve()
      },s*1000)
    })
  }
  const eat = (food) => {
    return new Promise((resolve, reject) => {
      console.log(`i'm eat ${food}`)
      resolve()
    })
  }


// 处理参数的顺序
  const handleArgs = (str) => {
    const argsArr = str.split('.')
    argsArr.forEach((item,index)=>{
      if(item.split('firstSleep').length>1){
        argsArr.splice(index,1)
        item = 'sleep' + item.split('firstSleep')[1]
        argsArr.splice(1,0,item)
      }
    })
    return argsArr
  }
// 按照参数顺序依次执行
  const asyncFn = async(args) => {
    for(let i=0;i<args.length;i++) {
      await eval(args[i])
    } 
  }
  asyncFn(handleArgs(`lazyMan('tom').sleep(3).eat('apple').firstSleep(2)`))
}