前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于 网红题 LazyMan 的个人实现

关于 网红题 LazyMan 的个人实现

作者头像
腾讯IVWEB团队
发布2020-06-24 16:10:22
2910
发布2020-06-24 16:10:22
举报

据说是微信面试题目:

代码语言:javascript
复制
实现一个LazyMan,可以按照以下方式调用:
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
 
以此类推。

我自己的实现如下:

代码语言:javascript
复制
class LazyManFunc {
  constructor (manName) {
    let self = this
    this.manName = manName
    this.eventList = []

    this.surprisedAppear()
    setTimeout(() => {
      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(() => {
        resolve()
      }, timeout)
    })
  }

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

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

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

  eat (meal) {
    this.eventList.push({
      exec: () => {
        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')

个人觉得思路实际上就是构建一个 LazyMan 对象并封装方法

每执行一次动作实际上就是队列push一个事件(event)如果是xxFirst 函数则是 unshift 一个事件(event)

关键点:setTimeout 0 , macrotask 会在 当前的 eventLoop 全部执行完成后在执行

所以 当链式调用全部结束后,执行 _publish

当执行 _publish 时 我们拿到的是一个 Promise 队列,我们使用 async + await 实现一个Promise 队列自执行

个人感觉这种面试题很有挑战性,充分考察了面试者关于 eventLoop 异步调用 对象封装的相关知识

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档