面试题目
实现一个LazyMan,可以按照以下方式调用:
LazyMan(‘Hank‘)
,输出:
Hi, This is Hank!
LazyMan(‘Hank‘).sleep(5).eat(‘dinner‘)
,输出:
Hi, This is Hank!
// 等待5秒
Weak 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
以此类推
题目解析
- 需要封装一个对象,并且这个对象提供不同的方法,比如
eat
- 能进行链式调用,那么每个调用方法,都必须返回当前对象
sleep
、sleepFirst
方法需要时异步的
解题思路
- 采用 ES6 的 class,来实现,封装对象
_LazyMan
- 提供一系列方法,比如
eat
。sleep
、sleepFirst
异步方法采用Promise
和setTimeout
实现 - 链式调用,考虑到其中含异步方法,采用任务队列及 ES6 的
async wait
实现。每次调用都往队列中加入方法,然后循环调用任务队列,而循环中通过异步实现异步的方法,保证正确。
具体实现
class _LazyMan {
constructor (name) {
this.taskQueue = [];
this.runTimer = null;
this.sayHi(name);
}
run () {
if (this.runTimer) {
clearTimeout(this.runTimer);
}
this.runTimer = setTimeout(async () => {
for (let asyncFun of this.taskQueue) {
await asyncFun()
}
this.taskQueue.length = 0;
this.runTimer = null;
})
return this;
}
sayHi (name) {
this.taskQueue.push(async () => console.log(`Hi, this is ${name}`));
return this.run();
}
eat (food) {
this.taskQueue.push(async () => console.log(`Eat ${food}`));
return this.run();
}
sleep (second) {
this.taskQueue.push(async () => {
console.log(`Sleep ${second} s`)
return this._timeout(second)
});
return this.run();
}
sleepFirst (second) {
this.taskQueue.unshift(async () => {
console.log(`Sleep first ${second} s`)
return this._timeout(second);
});
return this.run();
}
async _timeout (second) {
await new Promise(resolve => {
setTimeout(resolve, second * 1e3);
})
}
}
// 测试
var LazyMan = name => new _LazyMan(name)
// lazyMan('Hank');
lazyMan('Hank').sleep(10).eat('dinner');
// lazyMan('Hank').eat('dinner').eat('supper');
// lazyMan('Hank').sleepFirst(5).eat('supper');
原文地址:https://www.cnblogs.com/EnSnail/p/9866130.html
时间: 2024-11-13 07:57:35