前言、今天逛社区,无意间看到一道面试题,觉得很有意思,特此记录一下,题目如下
function LazyMan() {} //设计LazyMan函数满足下列需求
LazyMan('Tony');
// Hi I am Tony
LazyMan('Tony').sleep(10).eat('lunch');
// Hi I am Tony
// 等待了10秒...
// I am eating lunch
LazyMan('Tony').eat('lunch').sleep(10).eat('dinner');
// Hi I am Tony
// I am eating lunch
// 等待了10秒...
// I am eating diner
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
// Hi I am Tony
// 等待了5秒...
// I am eating lunch
// I am eating dinner
// 等待了10秒...
// I am eating junk food
个人觉得这个题目还是很有意思的,结合了Promise,async/await,和js事件循环,异步队列的知识。
捣鼓了半个小时,中间一直修改优化,最终实现了一个版本,有兴趣的可以参考一下:
function LazyMan(name) {
if(!(this instanceof LazyMan)) return new LazyMan(name)
this.name = name
this.isExecute = false //队列是否开始执行
this.cache = [] //缓存队列
this.init() //初始化需要做的事
}
LazyMan.prototype = {
init: function () {
console.log(`I am ${this.name}`)
},
eat: function(type) {
this.cache.push(async () => {
console.log(`${this.name} have ${type}`)
})
this.notify()
return this;
},
sleep: function (t=0) {
this.cache.push(async () => {
return new Promise(res => {
setTimeout(() => {
res()
},t)
})
})
this.notify()
return this
},
firstSleep: function (t) {
this.cache.unshift(async () => {
return new Promise(res => {
setTimeout(() => {
res()
},t)
})
})
this.notify()
return this
},
notify: function() {
if(!this.isExecute) {
this.isExecute = true
setTimeout(() => {
this.execute()
},0)
}
return this
},
execute: async function (i) {
i = i || 0
if(i > this.cache.length-1) {
this.isExecute = false
this.cache = []
return;
}
await this.cache[i]()
this.execute(i+1)
}
}