LazyMan 的实现

LazyMan 的实现

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 hxrealm (@hxrealm) on CodePen.