有些重试脚本会在两次请求之间 await sleep(5000),但进程收到退出信号时还得硬等完,挺烦。Node 内置的 node:timers/promises 可以配 AbortController,让等待本身也能被取消。
环境:Node.js 20+,Linux/macOS/Windows,只用内置模块。保存为 cancel-sleep-demo.mjs:
import { setTimeout as sleep } from 'node:timers/promises';
const controller = new AbortController();
process.once('SIGINT', () => {
console.log('\nabort sleep');
controller.abort();
});
async function main() {
try {
console.log('wait 10s, press Ctrl+C to cancel');
await sleep(10_000, undefined, { signal: controller.signal });
console.log('finished waiting');
} catch (error) {
if (error?.name === 'AbortError') {
console.log('cancelled cleanly');
return;
}
throw error;
}
}
await main();
跑一下:
node cancel-sleep-demo.mjs
小坑是 setTimeout 的第二个参数是 resolve 出来的值,不想传值也要占个 undefined,第三个参数才是 { signal }。写轮询、退避重试、优雅退出时很顺手。