实现一个 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
方法一:维护一个队列,在每个任务的结束调用 next 方法执行下一个任务。
class LazyMan {
constructor(name) {
this.name = name
this.sayName = this.sayName.bind(this)
this.next = this.next.bind(this)
this.queue = [this.sayName]
setTimeout(this.next, 0)
}
next(){
const currTask = this.queue.shift()
currTask && currTask()
}
sayName() {
console.log(`Hi! this is ${this.name}!`)
this.next()
}
holdOn(time) {
setTimeout(() => {
console.log(`Wake up after ${time} second`)
this.next()
}, time * 1000)
}
sleep(time) {
this.queue.push(this.holdOn(time))
return this
}
eat(meal) {
this.queue.push(() => {
console.log(`eat ${meal}`)
this.next()
})
return this
}
sleepFirst(time) {
this.queue.unshift(this.holdOn(time))
return this
}
}
const lazyMan = new LazyMan('abc')
lazyMan.sleep(10).eat('first')
方法二:Promise + async
class _LazyMan {
constructor(name) {
this.name = name
this.sayName = this.sayName.bind(this)
this.queue = [this.sayName]
setTimeout(async () => {
for (let todo of this.queue) {
await todo()
}
}, 0)
}
sayName() {
return new Promise((resolve) => {
console.log(`Hi! this is ${this.name}!`)
resolve()
})
}
holdOn(time) {
return () => new Promise(resolve => {
setTimeout(() => {
console.log(`Wake up after ${time} second`)
resolve()
}, time * 1000)
})
}
sleep(time) {
this.queue.push(this.holdOn(time))
return this
}
eat(meal) {
this.queue.push(() => {
console.log(`eat ${meal}`)
})
return this
}
sleepFirst(time) {
this.queue.unshift(this.holdOn(time))
return this
}
}
function LazyMan(name) {
return new _LazyMan(name)
}
LazyMan('LiMing').sleep(10).eat('food')
网友评论