lxinr/interview-question

2021/02/28 - 经典面试题: 实现一个LazyMan

Opened this issue · 0 comments

lxinr commented

题目

LazyMan('Hank')输出:
Hi! This is Hank!
LazyMan('Hank').sleep(10).eat('dinner')输出
Hi! This is Hank!
//等待10秒..
Wake up after 10
Eat dinner~
LazyMan('Hank').eat('dinner').eat('supper')输出
Hi This is Hank!
Eat dinner~
Eat supper~
LazyMan('Hank').sleepFirst(5).eat('supper')输出
//等待5秒
Wake up after 5
Hi This is Hank!
Eat supper

实现

写法一(类)

class _LazyMan {
  constructor(val) {
    this.queues = [] // 执行队列
    
    const queue = () => {
      console.log('Hi! This is ' + val)
      this.next()
    }
    this.queues.push(queue)
    setTimeout(() => { // 在下一个事件循环开始执行方法
      this.next()
    }, 0)
    return this
  }
  next() {
    const queue = this.queues.shift() // 先进先出
    queue && queue()
  }
  sleep(timer) {
    const queue = () => {
      setTimeout(() => {
        console.log(`Wake up after ${timer}`)
        this.next()
      }, timer * 1000)
    }
    this.queues.push(queue)
    return this
  }
  sleepFirst(timer) {
    const queue = () => {
      setTimeout(() => {
        console.log(`Wake up after ${timer}`)
        this.next()
      }, timer * 1000)
    }
    this.queues.unshift(queue)
    return this
  }
  eat(val) {
    const queue = () => {
      console.log(`Eat ${val}`)
      this.next()
    }
    this.queues.push(queue)
    return this
  }
}

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

写法二

function LazyMan(val) {
  var queues = []

  function next() {
    var queue = queues.shift()
    queue && queue()

    if (!queues.length) queues = null
  }

  const protos = {
    init() {
      var queue = function() {
        console.log('Hi! This is ' + val)
        next()
      }
      queues.push(queue)
      setTimeout(next, 0)
    },
    sleep(timer) {
      var queue = function() {
        setTimeout(function() {
          console.log('Wake up after ' + timer)
          next()
        }, timer * 1000)
      }
      queues.push(queue)

      return this
    },
    eat(info) {
      var queue = function() {
        console.log('Eat ' + info + '~')
        next()
      }
      queues.push(queue)
      return this
    },
    sleepFirst(timer) {
      var queue = function() {
        setTimeout(function() {
          console.log('Wake up after ' + timer)
          next()
        }, timer * 1000)
      }
      queues.unshift(queue)
      return this
    }
  }

  protos.init()

  return protos
}