Last active
February 17, 2017 07:37
-
-
Save oakland/eee90c3ef8b3f10ca827f424f69d8021 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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