https://www.pandanoir.info/entry/2021/04/21/234305
名前から既にワクワクするこのAPIは、なんとPromiseを返すsetTimeout、setInterval関数を提供しています!最高です…
というわけで今回はそれの紹介です。
await setTimeout(1000)
←これができるんです!素晴らしくないですか??
top-level await や for-awaitと組み合わせるとこんな感じで書けます
import { setTimeout } from 'timers/promises';
console.log('start');
await setTimeout(1000); // これでいける!!
console.log('1s passed');
import { setInterval } from 'timers/promises';
console.log('start');
for await (const startAt of setInterval(1000, Date.now()) {
console.log(Date.now() - startAt);
}
特に setTimeout は最高ですね…
キャンセルはAbortControllerを使ってできます。
import { setTimeout } from 'timers/promises'
const controller = new AbortController();
(async() => {
console.log('start');
await setTimeout(1000, null, { signal: controller.signal });
console.log('end');
})().catch(()=>console.log('aborted'));
// 上の setTimeout が発火する前にキャンセルしてみる
await setTimeout(500);
controller.abort();
AbortController ということは React の useEffect とも相性が良いです。
useEffect(() => {
const controller = new AbortController();
const { signal } = controller;
(async () => {
const res = await fetch('<http://example.com>', { signal });
await setTimeout(1000, null, { signal });
console.log(res);
})();
return () => controller.abort();
});
clearTimeout を使うよりグッとシンプルになりました。
型定義がまだなさそうだったので自分で書きました。おそらく合ってますが間違えている可能性はあります。
module 'timers/promises' {
const setTimeout: <T>(
delay?: number,
value?: T,
options?: { ref?: boolean; signal?: AbortSignal }
) => Promise<T>;
const setImmediate: <T>(
value?: T,
options?: { ref?: boolean; signal?: AbortSignal }
) => Promise<T>;
const setInterval: <T>(
delay?: number,
value?: T,
options?: { ref?: boolean; signal?: AbortSignal }
) => AsyncIterable<T>;
}