题目描述
思路分析
- 用构造函数
return this来实现链式调用
LazyMan('Jack', console.log).eat('banana').eat('apple');
function LazyMan(name, logFn) {
return new LazyManInstance(name, logFn);
}
- setTimeout属于异步任务,怎么解决排队呢,可以通过创建一个队列和状态来完成等待,调用每个方法负责添加事件到队列,状态表明可以继续向后执行:
class LazyManInstance {
eat(value) {
this.tasks.push({ type: 'eat', payload: value });
return this;
}
sleep(value) {
this.tasks.push({ type: 'sleep', payload: value });
}
// 统一状态管理
next() {
const task = this.tasks.shift();
// next 方法就是控制执行的开关
switch(action) {
case 'eat':
console.log(task.payload);
this.next();
break;
case 'sleep':
setTimeout(() => {
console.log(task.payload);
this.next();
break;
}, payload * 1000);
}
}
}
以上我们就完成了排队,还需要完成 sleepFirst 操作,我们只需要新增一个队列 每次都会在最开始执行的队列 即可:
sleepFirst(time) {
this.preTask.push('sleep');
return this;
}
// 先从preTask中找优先执行的任务
next() {
const task = this.preTask.shift() || this.tasks.shift();
}
AC代码
class LazyManInstance {
constructor(name, logFn) {
this.name = name;
this.log = logFn;
this.tasks = [];
this.preTasks = [];
this.init();
setTimeout(() => {
this.next()
}, 0);
}
init() {
this.tasks.push({ type: 'init' })
return this;
}
eat(value) {
this.tasks.push({type: 'eat', payload: value});
return this;
}
sleep(value) {
this.tasks.push({type: 'sleep', payload: value});
return this;
}
sleepFirst(value) {
this.preTasks.push({type: 'sleep', payload: value});
return this;
}
next() {
let task = this.preTasks.shift() || this.tasks.shift();
if (!task) {
return
}
switch (action) {
case 'init':
this.log(`Hi, I'm ${this.name}.`);
this.next();
break;
case 'eat':
this.log(`Eat ${task.value}.`);
this.next();
break;
case 'sleep':
setTimeout(() => {
this.log(`Wake up after ${task.type} second.`)
this.next()
break;
}, task.value * 1000);
}
}
}
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情