實現一個方法的鏈式調用
作者:一川
這個需求是一個典型的異步鏈式調用場景,尤其是?sleep?延遲后再繼續執行后續操作。實現時關鍵在于:每次調用都注冊一個異步任務;按順序排隊執行(使用?Promise?鏈或任務隊列);每個方法返回?this?以保持鏈式調用。
題目描述
請使用 TypeScript 實現一個支持鏈式調用的 Cat 類,要求如下:
cat.say("Tom"):立即輸出hello Tom到控制臺;cat.sleep(3000):等待 3000 毫秒后再繼續執行后續任務;cat.bye("Bye"):輸出 Bye 到控制臺。
調用示例:
const cat = new Cat();
cat.say("Tom").sleep(3000).bye("Bye");期望輸出:
hello Tom
# 等待 3 秒...
Bye題目解析
這個需求是一個典型的 異步鏈式調用 場景,尤其是 sleep 延遲后再繼續執行后續操作。實現時關鍵在于:
- 每次調用都注冊一個異步任務;
- 按順序排隊執行(使用
Promise鏈或任務隊列); - 每個方法返回
this以保持鏈式調用。
代碼實現
class Cat {
private taskQueue: (() => Promise<void>)[] = [];
constructor() {
// 自動開始執行任務隊列
Promise.resolve().then(() => this.runQueue());
}
private async runQueue() {
for (const task of this.taskQueue) {
await task();
}
}
say(name: string): this {
this.taskQueue.push(() => {
return new Promise<void>((resolve) => {
console.log("hello", name);
resolve();
});
});
return this;
}
sleep(ms: number): this {
this.taskQueue.push(() => {
return new Promise<void>((resolve) => {
setTimeout(resolve, ms);
});
});
return this;
}
bye(msg: string): this {
this.taskQueue.push(() => {
return new Promise<void>((resolve) => {
console.log(msg);
resolve();
});
});
return this;
}
}
// 使用方式
const cat = new Cat();
cat.say("Tom").sleep(3000).bye("Bye");說明:
- taskQueue 是一個異步任務列表。
- 每個方法通過 this.taskQueue.push(() => Promise) 添加一個任務。
- 構造函數中立即開始異步執行任務隊列。
- sleep 實現延遲,后續任務自然排隊執行。
拓展
如果要進行逆向鏈式調用,如何實現呢?
cat.bye("Bye").sleep(2000).say("Say");執行順序:
Say
# 等待 2 秒...
Bye所有方法仍然鏈式調用,但執行順序以調用順序為準,同時 sleep 是延遲“下一個任務”的執行,而不是“當前任務”的延遲。
class Cat {
private queue: { fn: () => void; delay: number }[] = [];
private nextDelay = 0;
constructor() {
Promise.resolve().then(() => this.run());
}
private async run() {
for (const task of this.queue) {
if (task.delay > 0) {
await new Promise((res) => setTimeout(res, task.delay));
}
task.fn();
}
}
private addTask(fn: () => void): this {
this.queue.push({ fn, delay: this.nextDelay });
this.nextDelay = 0; // reset after applying
return this;
}
say(msg: string): this {
return this.addTask(() => {
console.log(msg);
});
}
bye(msg: string): this {
return this.addTask(() => {
console.log(msg);
});
}
sleep(ms: number): this {
this.nextDelay = ms; // apply to next task
return this;
}
}責任編輯:武曉燕
來源:
宇宙一馬平川


























