LazyMan 题目介绍
实现一个 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
以此类推。
考点
- 链式调用
- 设计模式
es6 实现
/**
* lazyman匿名类
* @class _LazyMan
*/
class _LazyMan {
// 任务列表
taskList = [];
// 发布实际上调用的方法
runFunc = {
hi(thisClass, name) {
thisClass.log(`Hi, this is ${name}!`);
thisClass.publish();
},
eat(thisClass, food) {
thisClass.log(`Eat ${food}~`);
thisClass.publish();
},
sleep(thisClass, time) {
setTimeout(() => {
thisClass.log(`Wake up after ${time}!`);
thisClass.publish();
}, time * 1000);
},
sleepFirst(thisClass, time) {
thisClass.runFunc.sleep(thisClass, time);
}
};
constructor(name) {
this.hi(name);
// 触发发布
setTimeout(() => {
this.publish();
});
}
hi(name) {
this.subscribe('hi', name);
return this;
}
// 暴露给外部的方法
eat(food) {
this.subscribe('eat', food);
// 实现链式调用的关键
return this;
}
sleep(time) {
this.subscribe('sleep', time);
return this;
}
sleepFirst(time) {
this.subscribe('sleepFirst', time);
return this;
}
// 订阅
subscribe(funcName, ...args) {
const task = {
name: funcName,
args
};
if (funcName === 'sleepFirst') {
this.taskList.unshift(task);
} else {
this.taskList.push(task);
}
}
// 发布
publish() {
if (this.taskList.length > 0) {
this.run(this.taskList.shift());
}
}
// 执行
run(task) {
this.runFunc[task.name](this, ...task.args);
}
// 打印
log(str) {
console.log(str);
}
}
// 暴露给外部的方法
function LazyMan(name) {
return new _LazyMan(name);
}
// 调用
LazyMan('Tom')
.eat('lunch')
.sleep(2)
.eat('dinner')
.sleepFirst(1);
// 结果:
// Wake up after 1!
// Hi, this is Tom!
// Eat lunch~
// Wake up after 2!
// Eat dinner~
typescript 实现
// 定义任务模型
interface Task {
name: string;
args: any[];
}
/**
* lazyman匿名类
* @class _LazyMan
*/
class _LazyMan {
// 任务列表
private taskList: Task[] = [];
// 发布实际上调用的方法
private runFunc = {
hi(thisClass: _LazyMan, name: string) {
thisClass.log(`Hi, this is ${name}!`);
thisClass.publish();
},
eat(thisClass: _LazyMan, food: string) {
thisClass.log(`Eat ${food}~`);
thisClass.publish();
},
sleep(thisClass: _LazyMan, time: number) {
setTimeout(() => {
thisClass.log(`Wake up after ${time}!`);
thisClass.publish();
}, time * 1000);
},
sleepFirst(thisClass: _LazyMan, time: number) {
thisClass.runFunc.sleep(thisClass, time);
}
};
constructor(name: string) {
this.hi(name);
// 触发发布
setTimeout(() => {
this.publish();
});
}
private hi(name: string) {
this.subscribe('hi', name);
return this;
}
// 暴露给外部的方法
eat(food: string) {
this.subscribe('eat', food);
// 实现链式调用的关键
return this;
}
sleep(time: number) {
this.subscribe('sleep', time);
return this;
}
sleepFirst(time: number) {
this.subscribe('sleepFirst', time);
return this;
}
// 订阅
private subscribe(funcName: string, ...args: any[]) {
const task: Task = {
name: funcName,
args
};
if (funcName === 'sleepFirst') {
this.taskList.unshift(task);
} else {
this.taskList.push(task);
}
}
// 发布
private publish() {
if (this.taskList.length > 0) {
this.run(this.taskList.shift());
}
}
// 执行
private run(task: Task) {
this.runFunc[task.name](this, ...task.args);
}
// 打印
private log(str: string) {
console.log(str);
}
}
// 暴露给外部的方法
function LazyMan(name: string) {
return new _LazyMan(name);
}
// 调用
LazyMan('Tom')
.eat('lunch')
.sleep(2)
.eat('dinner')
.sleepFirst(1);
参考
本文由 陈曦宇 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Nov 4, 2019 at 10:59 pm