一道前端流程控制面试题

最近在面试时遇到这样一道笔试题,觉得很有意思,拿出来分享一下。
看题目:

实现一个 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

刚拿到题目的时候还是比较懵的,无从下手,不过为了offer还是很快的静下心来去分析题目。

  1. 所有的调用都是基于 LazyMan 的链式调用,这样可以把 LazyMan 构造成一个构造函数,返回的实例具有一些方法;
  2. 实例方法都有链式调用的特征;
  3. eat 方法较为简单,直接输出参数即可
  4. sleep 方法会暂停链式调用,等待相应时间后继续,考虑使用 setTimeout ;
  5. sleepFirst 方法比较特殊,与 sleep 类似,但是优先级最高,无论在何处调用,都会从头开始暂时整个链式调用过程;
  6. 考虑到 sleep 和 sleepFirst 方法的特殊性,我决定使用任务队列来处理“暂停”操作。

接下来我尝试按照上面的思路去用代码实现。

class LazyManGenerator {
    constructor(name) {
        this.taskArray = []
        const task = () => {
            console.log(`Hi! This is ${name}`)
            this.next()
        }

        this.taskArray.push(task);
		// 防止立即执行,要去等待数组全部完成后再执行任务队列中的任务。
        setTimeout(() => { this.next(); }, 0)
    }

    next() {
        // 从头取出任务执行
        const task = this.taskArray.shift()
        task && task()
    }

    sleep(time) {
        this.sleepTask(time, false)
            // 支持链式调用
        return this
    }

    sleepFirst(time) {
        this.sleepTask(time, true)
        return this
    }

    sleepTask(time, prior) {
        const task = () => {
            setTimeout(() => {
                console.log(`Wake up after ${time}`)
                this.next()
            }, time * 1000)
        }

        // 如果是sleepFirst方法,从头部加入当前task,否则正常从当前尾部添加
        if (prior) {
            this.taskArray.unshift(task);
        } else {
            this.taskArray.push(task);
        }

        return this;
    }

    eat(name) {
        const task = () => {
            console.log(`Eat ${name}`)
            this.next()
        }

        this.taskArray.push(task)
        return this
    }
}

function LazyMan(name) {
    // 返回LazyManGenerator构造函数实例
    return new LazyManGenerator(name)
}

代码其实并不难,就是上面分析的实现。中心思想就是方法不去立即执行,而是去按照特定的顺序添加到 taskArray 数组中,然后待链式调用完成后(任务全部添加到taskArray中),再去依次执行 taskArray 数组中的任务。

实现到这已经算是及格了,不过面试官还是继续追问是否有更好的实现,可能是由于 next 的原因,让我想到了 koa 的中间件的实现,简单的说了下思路,其实就是一个简单的中间件流程控制。有能力的童鞋可以自己尝试去实现以下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值