题目描述
请实现一个 HardMan(name)
函数,支持链式调用以下方法:
study()
:表示开始学习,输出"I am studying"
。rest(sec)
:表示休息,等待 sec 秒后输出"I have rested for ${sec} seconds"
,然后继续执行后续链式调用。restFirst(sec)
:在做所有事情之前先休息 sec 秒钟
示例:
HardMan(jiaqi).study().rest(5).study().restFirst(10)
说明:
- 输出应依次为:
- `My name is jiaqi
- (等待10秒)
"Yeah, I have rested for 10 seconds"
"I am studying"
- (等待5秒)
"I have rested for 5 seconds"
"I am studying"
用类实现
javascript
class HardMan {
constructor(name) {
this.queue = []; // 初始化一个队列
console.log(`My name is ${name}`);
Promise.resolve().then(() => {
let sequence = Promise.resolve();
this.queue.forEach((item) => {
sequence = sequence.then(item);
});
})
}
study() {
this.queue.push(() => {
console.log("I am studying");
});
return this; // 返回实例以支持链式调用
}
holdOn(sec) {
return () => {
return new Promise((resolve) => {
// 注意箭头函数中的 return
setTimeout(() => {
console.log(`rest for ${sec} seconds`);
resolve(); //
}, sec * 1000);
});
}
}
rest(sec) {
this.queue.push(this.holdOn(sec));
return this; // 返回实例以支持链式调用
}
restFirst(sec) {
this.queue.unshift(this.holdOn(sec));
return this; // 返回实例以支持链式调用
}
}
// 测试代码
let jiaqi = new HardMan("jiaqi");
jiaqi
.study()
.rest(5)
.study()
.restFirst(2);
在这里最需要注意的是 holdOn
函数的返回值,要与[[202407012319-LazyMan]] 中相应的返回值一起理解,理解箭头函数的返回值。
[!PDF|yellow] [[JavaScript权威指南(原书第7版)(经典的JavaScript犀牛书全新升级) (O''''Reilly精品图书系列)_LT.pdf#page=475&selection=15,0,18,30&color=yellow|📖]]
在期约链中,一个环节返回(或抛出)的值会成为下一个环节的输入。因此每个环节返回什么至关重要。实际开发中,忘记从回调函数中返回值是导致期约相关问题的常见原因。而使用 JavaScript的箭头函数快捷语法又让这个问题雪上加霜。
当箭头函数没有大括号包裹时,箭头函数会隐式地返回单个表达式的值。
当箭头函数有大括号包裹时,需要用 return
显式地返回值。
用函数实现
javascript
function HardMan(name) {
let queue = [];
Promise.resolve().then(()=>{
let sequence = Promise.resolve();
queue.forEach((item)=>{
sequence = sequence.then(item);
});
})
console.log(`My name is ${name}`);
// 立即返回三个方法,以便支持链式调用
return {
study() {
queue.push(() => {
console.log("I am studying");
});
return this; // 返回当前对象以支持链式调用
},
holdOn(sec){
return ()=>{
return new Promise((resolve)=>{
setTimeout(()=>{
console.log(`rest for ${sec} seconds`);
resolve();
}, sec * 1000);
});
}
},
rest(sec) {
queue.push(this.holdOn(sec));
return this; // 返回当前对象以支持链式调用
},
restFirst(sec) {
queue.unshift(this.holdOn(sec));
return this; // 返回当前对象以支持链式调用
}
};
}
// 测试代码
HardMan("jiaqi")
.study()
.rest(5)
.study()
.restFirst(2);