前端面试中的LazyMan

2,005 阅读1分钟

实现一个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
以此类推。

题目解析:看起来是链式调用并且有流程控制其中sleepFisrt要在所有函数之前执行。大致的思路是创建一个任务队列,将每一项任务(输出名字、吃饭、睡觉)都放进队列里按顺序执行。代码如下:

function LazyMan(name){
    let _lazyMan = {
        sayHi : function () {
            queue.push(() => {
                    console.log('Hi! This is'+name)
                    this.next();
            })
        },
        eat : function (food) {
            queue.push(() => {
                    console.log('Eat '+food)
                    this.next();
            })
            return this;
        },
        sleep : function (second) {
            queue.push(() => {
                setTimeout(() => {
                    console.log("wake  up after "+ second + "秒")
                    this.next();
                },second * 1000)
            })
            return this;
        },
        sleepFirst : function (second) {
            queue.unshift(() => {
                setTimeout(() => {
                    console.log("wake  up after "+ second + "秒")
                    this.next();
                },second * 1000)
            })
            return this;
        },
        next : function () {//函数依次执行
            let fn = queue.shift();
            fn && fn();
        }
    }
    let queue = [];//存放函数的任务队列
    _lazyMan.sayHi();//将打招呼放进队列
    setTimeout(function () {//开始执行任务队列的里的函数
        _lazyMan.next();
    })
    return _lazyMan;
}

// LazyMan("kakao")
// LazyMan("kakao").eat("apple").eat("banana")
// LazyMan("kakao").sleep(3).eat("apple")
// LazyMan("kakao").sleepFirst(3).eat("apple")