實現:
// Person('Li')
/* 輸出:
Hi! This is Hank!
*/
// Person('Dan').sleep(3).eat('dinner')
/* 輸出:
Hi! This is Hank!
// 等待10秒..
Wake up after 10
Eat dinner~
*/
// Person('Jerry').eat('dinner~').eat('supper~')
/* 輸出:
Hi This is Hank!
Eat dinner~
Eat supper~
*/
Person('Smith').sleepFirst(2).eat('supper')
/* 等待5秒,輸出
Wake up after 5
Hi This is Hank!
Eat supper
*/
function Person(name) {
return new CreatePerson(name)
}
class CreatePerson {
constructor(name){
this.tasks = [] // 核心,使用佇列(陣列)來儲存要執行的函式
this.tasks.push(()=> console.log(`Hi! This is ${name}`))
this.runTask()
}
runTask() {
// 關鍵!利用宏任務將事件延遲執行
// 如果遇到 sleepFirst,可以先將 sleepFirst 壓入任務佇列,然後按順序執行
setTimeout(() => this.exector())
}
exector() {
if(this.tasks.length === 0) return // 遞迴出口
const task = this.tasks.shift() // 取出任務
if(typeof task === "number") {
setTimeout(() => {
console.log(`Wake up after ${task}`)
this.exector() // 遞迴自身
}, 2000)
}
if (typeof task === 'function') {
task()
this.exector() // 遞迴自身
}
return this
}
// 維護各種任務,用任務佇列儲存
eat(food) {
this.tasks.push(() => console.log(`Eat ${food}~`)) // 常規操作,塞進任務佇列
return this
}
sleep(time) {
this.tasks.push(time) // 常規操作,塞進任務佇列
return this
}
sleepFirst(time) {
console.log(1);
this.tasks.unshift(time) // 執行:塞進第一項!
return this
}
}