微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

微软笔试题:如何实现一个 LazyMan

2017-01-03 19:32 前端大全

(点击上方公众号,可快速关注)


作者:伯乐在线专栏作者 - Natumsol

如有好文章投稿,请点击 → 这里了解详情

如需转载,发送「转载」二字查看说明


3月份找实习的时候,微信面试官给了我一套笔试题,今天整理时无意中翻了出来,其中有一道题特别有意思:


实现一个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流程控制,问题的关键是如何实现任务的顺序执行。在Express有一个类似的东西叫中间件,这个中间件和我们这里的吃饭、睡觉等任务很类似,每一个中间件执行完成后会调用next()函数,这个函数用来调用下一个中间件。


对于这个问题,我们也可以利用相似的思路来解决,首先创建一个任务队列,然后利用next()函数来控制任务的顺序执行:


function _LazyMan(name) {

    this.tasks = [];  

    var self = this;

    var fn =(function(n){

        var name = n;

        return function(){

            console.log("Hi! This is " + name + "!");

            self.next();

        }

    })(name);

    this.tasks.push(fn);

    setTimeout(function(){

        self.next();

    }, 0); // 在下一个事件循环启动任务

}

/* 事件调度函数 */

_LazyMan.prototype.next = function() {

    var fn = this.tasks.shift();

    fn && fn();

}

_LazyMan.prototype.eat = function(name) {

    var self = this;

    var fn =(function(name){

        return function(){

            console.log("Eat " + name + "~");

            self.next()

        }

    })(name);

    this.tasks.push(fn);

    return this; // 实现链式调用

}

_LazyMan.prototype.sleep = function(time) {

    var self = this;

    var fn = (function(time){

        return function() {

            setTimeout(function(){

                console.log("Wake up after " + time + "s!");

                self.next();

            }, time * 1000);

        }

    })(time);

    this.tasks.push(fn);

   return this;

}

_LazyMan.prototype.sleepFirst = function(time) {

    var self = this;

    var fn = (function(time) {

        return function() {

            setTimeout(function() {

                console.log("Wake up after " + time + "s!");

                self.next();

            }, time * 1000);

        }

    })(time);

    this.tasks.unshift(fn);

    return this;

}

/* 封装 */

function LazyMan(name){

    return new _LazyMan(name);

}



觉得本文对你有帮助?请分享给更多人

关注「前端大全」,提升前端技能


专栏作者简介 ( 点击 → 加入专栏作者 


Natumsol:阿里巴巴 前端工程师

 
前端大全 更多文章 唯快不破:Web 应用的 13 个优化步骤 微软笔试题:如何实现一个 LazyMan 程序员为什么要时刻保持危机感? 9 款极佳的 JS 移动应用程序开发框架 </2016><2017> 来自前端的特别祝福
猜您喜欢 这次它很低调:谷歌正式发布Android4.4和Nexus 5 不要忽视C语言 Rancher与Windows&nbsp;Server2016&nbsp;AD集成登录验证 当程序员在谈论bug时其实是在讨论什么? 美团COO:我是如何帮美团打造出一支地推铁军?