前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >什么?没听说过LazyMan,没关系,看完你就知道了

什么?没听说过LazyMan,没关系,看完你就知道了

作者头像
FE情报局
发布2022-12-05 10:14:29
4900
发布2022-12-05 10:14:29
举报
文章被收录于专栏:FE情报局

前沿

前几天一个小伙伴面试,发现一个很有意思的面试题,之前自己也没有接触过,分享给大家。顺便在此记录一下,希望能够加深一下印象

题目

实现一个LazyMan,可以按照以下的方式调用

代码语言:javascript
复制
LazyMan('前端小本子')
// 输出:前端小本子

LazyMan('前端小本子').sleep(10).look('看完了')
// 输出:前端小本子
// 等待10秒
// 看完了

LazyMan('前端小本子').look('开始看').look('看完了')
// 输出:前端小本子
// 开始看
// 看完了

LazyMan('前端小本子').sleepFirst(5).look('看完了')
// 等待5秒
// 输出:前端小本子
// 看完了

分析

通过上面的题目大家不难看出,这是一种JavaScript的控制流的形式,这个问题的关键就是我们如何实现任务的顺序执行。

用过Express的应该都知道有个叫中间件的东西,中间件是什么,就跟我们题目中的等待以及看完了类似,当一个中间件完成之后,调用一下next然后执行下一个中间件,有了这个想法,那么我们就可以考虑实现了。

当然,还要跟大家啰嗦一点,就是这里还涉及到的知识点,就是事件轮训机制,队列等,所以当前我们要创建对应的任务队列,然后利用next进行任务的执行顺序,开搞

代码实现

代码语言:javascript
复制
// 定义一个LazyMan的构造函数
class _LazyMan {
  constructor(name) {
    this.tasks = [] //队列
    const task = () => {
      console.log(name)
      this.next()
    }
    this.tasks.push(task)
    setTimeout(() => {
      this.next()
    }, 0)
  }
  // 定义next函数,取到第一个函数,然后执行对应的方法,没有就不执行
  next() {
    const task = this.tasks.shift()
    task && task()
  }
  // 定义look方法
  look(something) {
    const task = () => {
      console.log(something)
      this.next()
    }
    this.tasks.push(task)
    // 返回this是为了链式调用
    return this
  }
  // 定义sleep方法
  sleep(time) {
    this._sleepWrapper(time, false)
    return this
  }
  // sleepFirst方法
  sleepFirst(time) {
    this._sleepWrapper(time, true)
    return this
  }
  // 封装一下延时函数,第一个参数是延时时间,第二个为是否要推送到队列首位
  _sleepWrapper(time, first) {
    const task = () => {
      setTimeout(() => {
        console.log(`等待${time}秒`)
        this.next()
      }, time*1000)
    }
    if(first){
      this.tasks.unshift(task)
    }else{
      this.tasks.push(task)
    }
  }
}

const LazyMan = (name) => {
  return new _LazyMan(name)
}

结尾

顺便说一下,定时器里面去return this是不行的,定时器属于异步任务,通过事件循环调用回调函数,然而,同步任务会优先执行,也就是等到再执行异步任务的时候,变量已经成undefined了,原理就跟我们之前常碰到过的异步任务进行遍历最终结果一直是最后一个类似,如下,实在不明白就补一下js基础知识,奉上

代码语言:javascript
复制
function testAsync() {
    for(var i = 0; i < 5; i++){
        setTimeout(function() {
            console.log(i)
        },i*1000)
    }
}
testAsync()
// 最终,每隔一秒打印出来的都是5

参考资料[1]

Reference

[1]

参考资料: https://zhuanlan.zhihu.com/p/22387417

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FE情报局 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前沿
  • 题目
  • 分析
  • 代码实现
  • 结尾
    • Reference
    相关产品与服务
    消息队列 TDMQ
    消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档