Wechat interview topic:

To implement a LazyMan, call LazyMan("Hank") Output: Hi! This is Hank! LazyMan ("Hank").sleep(10).eat("dinner"Output) Hi! This is Hank! // Wait 10 seconds.. 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"// Wait 5 seconds Wake up after 5 Hi This is Hank! Eat supper and so on.Copy the code

My own implementation is as follows:

class LazyManFunc {
  constructor (manName) {
    let self = this
    this.manName = manName
    this.eventList = []

    this.surprisedAppear()
    setTimeout((a)= > {
      this._publish()
    }, 0)
    return this
  }

  static LazyMan (manName) {
    return new LazyManFunc(manName)
  }

  async _publish () {
    for (let i = 0; i < this.eventList.length; i++) {
      let event = this.eventList[i]
      await event.exec()
    }
    return this
  }

  _sleep (timeout) {
    return new Promise((resolve) = > {
      setTimeout((a)= > {
        resolve()
      }, timeout)
    })
  }

  surprisedAppear () {
    this.eventList.push({
      exec: (a)= > {
        return new Promise((resolve) = > {
          console.log('Hi! This is ! '.this.manName)
          resolve()
        })
      },
      eventName: 'appear'
    })
    return this
  }

  sleep (timeout) {
    this.eventList.push({
      exec: (a)= > {
        return this._sleep(timeout * 1000)
          .then((a)= > {
            console.log('Wake up after ', timeout)
          })
      },
      eventName: 'sleep'
    })
    return this
  }

  sleepFirst (timeout) {
    this.eventList.unshift({
      exec: (a)= > {
        return this._sleep(timeout * 1000)
          .then((a)= > {
            console.log('Wake up after ', timeout)
          })
      },
      eventName: 'sleepFirst'
    })
    return this
  }

  eat (meal) {
    this.eventList.push({
      exec: (a)= > {
        return new Promise((resolve) = > {
          console.log('Eat ', meal)
          resolve()
        })
      },
      eventName: 'eat'
    })
    return this}}const LazyMan = LazyManFunc.LazyMan

LazyMan('Owen')
  .eat('lunch')
  .sleepFirst(2)
  .sleep(1)
  .eat('dinner')
Copy the code

I think the idea is actually to build a LazyMan object and encapsulate the method and every time you perform an action it’s actually a queue push an event and if it’s xxFirst it’s unshift an event

Key point: setTimeout 0, MacroTask will execute after the current eventLoop has completed, so _publish will be executed after the chain calls have completed

When we publish we get a Promise queue and we implement a Promise queue with async + await

This is a challenging interview question that examines the candidate’s knowledge of encapsulating the eventLoop asynchronous call object