Skip to content

Instantly share code, notes, and snippets.

@oakland
Last active February 17, 2017 07:37
Show Gist options
  • Save oakland/eee90c3ef8b3f10ca827f424f69d8021 to your computer and use it in GitHub Desktop.
Save oakland/eee90c3ef8b3f10ca827f424f69d8021 to your computer and use it in GitHub Desktop.
// https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651551620&idx=1&sn=509e8ff624cf676d35cb31315c87937e&chksm=8025a045b75229532293650e196403fc7558acb0b3e563bd87d21743371969ef97cc3d95b366&mpshare=1&scene=1&srcid=02158YYyKvXAJKAQTF0gdpHA&pass_ticket=HqKZKbs0BepJwfdcm3j3eBHYCepsXSrvyAfwKNyyo6o%3D#rd
// 最近一个面试题目很火,在网上找到一个答案,自己看了很多遍,对整个流程已经比较了解了,然后自己又简单修改了一下,记录下来。有想不懂的地方,大家可以打断点测试,了解整个过程是什么。
// LazyMan('Hank').sleep(3).eat('dinner'); 的过程是先执行所有的原型链上的方法,这个过程相当于把所有的 fn 都推入 tasks 这个数组之中,而 sleepFirst 则是放在最前面的。
// 然后再执行 setTimeout(function() {self.next()}, 0) 这个异步的函数,通过 next 这个函数的设计,一次次去执行 tasks 中所有的 fn。而所有的 fn 都是在执行之后再调用 next() 进而调用下一个 fn。
// setTimeout(function() {self.next()}, 0) 的设计非常巧妙,是开一个异步的进程,但是在所有的同步没有执行完毕之前,这个函数是不会执行的。所以肯定是所有的链式调用结束之后再开始self.next()。
// 整个这个设计还牵扯到很多技巧和概念,比如 闭包,数组的操作方法,setTimeout() 异步设计,原型链,链式调用,还有 fn && fn() 这个技巧等等。值得仔细研究。
// 这里面还有一个关于 setTimeout 的深入理解过程,参阅这篇文章: http://www.whohelpme.com/b/detail/121.html
function _LazyMan(name) {
this.tasks = [];
var self = this;
var fn = function() {
console.log("Hi " + name);
self.next();
}
this.tasks.push(fn);
setTimeout(function() {
self.next();
}, 0)
}
_LazyMan.prototype.next = function() {
var fn = this.tasks.shift();
fn && fn();
}
_LazyMan.prototype.eat = function(sth) {
var self = this;
var fn = function() {
console.log("Eat " + sth);
self.next();
}
this.tasks.push(fn);
return this;
}
_LazyMan.prototype.sleep = function(time) {
var self = this;
var fn = function() {
setTimeout(function() {
console.log("Wake up in " + time + " seconds");
self.next();
}, time*1000)
}
this.tasks.push(fn)
return this;
}
_LazyMan.prototype.sleep = function(time) {
var self = this;
var fn = function() {
setTimeout(function() {
console.log("Wake up in " + time + " seconds");
self.next();
}, time*1000)
}
this.tasks.unshift(fn)
return this;
}
function LazyMan(name) {
return new _LazyMan(name);
}
LazyMan('Hank').sleep(3).eat('dinner');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment