共计 1480 个字符,预计需要花费 4 分钟才能阅读完成。
JavaScript 实现一个 LazyMan
最近看到一个面试题,很有意思,于是记录了下来。
需求
实现一个 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
以此类推。
首先简单分析一下功能是什么样的,首先一个函数,传一个参数,链式调用方法。先定义的事件先响应,其中 sleepFirst 这个事件后定义,但也是最先响应的,特殊处理。
于是可以理解为,这是一个简单有点特别的队列。
实现过程
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);
}
代码实现来源:http://web.jobbole.com/89626/
正文完