LazyMan是一道javascript面试题,第一次听说LazyMan一词是与ing70聊天中获得,本文主要是说说自己的实现思路和方法。

题目如下:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

以此类推。

分析思路

根据经验猜测此题可参考jQuery中delay()、PHP中sleep()Express中next()中间件等方法的实现原理。也是典型的JavaScript流程控制,因此问题的关键是如何实现任务的顺序执行。

考查关键

  • 链式调用
  • _next()流程控制
  • 定时器的使用(setTimeout)
  • 数组常用方法的掌握(pop、push、shift、unshift)
  • 代码的封装(类、构造函数、原型链等)

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
(function(){
function LazyMan(name){
var that = this;
this._func = []; // 函数执行任务队列
this.name = name;
this._add({info: 'Hi! This is ' + this.name + '!'});
// 下一次事件循环时执行
setTimeout(function(){
that._next();
},0);
}

// _next维持任务队列中函数的执行
LazyMan.prototype._next = function(){
var func = this._func.shift();
func && func();
}

// 添加任务到队列
LazyMan.prototype._add = function(obj){
var that = this;
var fn = function(){
obj.info && console.log(obj.info);
if(obj.time && obj.time > 0){
setTimeout(function(){
that._next();
}, obj.time * 1000);
} else {
that._next();
}
};
// 添加到队列末端
!!obj.special == false && this._func.push(fn);
// 添加到队列前端
!!obj.special == true && this._func.unshift(fn);
}

LazyMan.prototype.eat = function(shit){
this._add({info: 'Eat ' + shit + '~'});
return this;
}

LazyMan.prototype.sleep = function(time){
this._add({info: 'Wake up after ' + time, time: time, special: false});
return this;
}

LazyMan.prototype.sleepFirst = function(time){
this._add({info: 'Wake up after ' + time, time: time, special: true});
return this;
}

var _lazyMan = function(name){
return new LazyMan(name);
}

window.LazyMan = _lazyMan;
})();

运行结果(在线运行)

请打开console控制台,查看运行结果。

See the Pen pwrrjY by hankewins (@hankewins) on CodePen.