AbortSignal
Claude Code.icon
AbortSignal は、非同期処理を「外部からキャンセルする」ための標準Web API です。
基本の仕組み
AbortController と AbortSignal はペアで使います。
code:js
const controller = new AbortController();
const signal = controller.signal;
// signal を非同期処理に渡す
fetch('/api/data', { signal });
// どこかのタイミングでキャンセル
controller.abort();
AbortController: キャンセルを「発火させる」側。abort() メソッドを持つ。
AbortSignal: キャンセルを「受け取る」側。非同期処理に渡す。
役割が分離しているのがポイントです。キャンセルする権限(controller)と、キャンセルを監視する側(signal)を分けることで、signal を渡された関数は「中断を検知するだけ」で「自分から中断させることはできない」状態にできます。
signal の中身
code:js
signal.aborted // true / false(中断済みか)
signal.reason // 中断理由(abort(reason) で渡した値)
signal.throwIfAborted() // 中断済みなら例外を投げる
// イベントで監視
signal.addEventListener('abort', () => {
console.log('中断された:', signal.reason);
});
よくある使い方
1. fetch のキャンセル
code:js
const controller = new AbortController();
const promise = fetch(url, { signal: controller.signal });
// 5秒後にタイムアウト
setTimeout(() => controller.abort(), 5000);
try {
const res = await promise;
} catch (e) {
if (e.name === 'AbortError') {
console.log('リクエストがキャンセルされました');
}
}
中断されると Promise は AbortError で reject されます。
2. タイムアウトのショートカット
code:js
// 自前で setTimeout + controller を書かなくていい
fetch(url, { signal: AbortSignal.timeout(5000) });
3. 複数の signal をまとめる
code:js
// どれか1つでも中断されたら中断
const signal = AbortSignal.any([
userCancelSignal,
AbortSignal.timeout(5000),
]);
自作の非同期関数で対応する
自分の関数を「キャンセル可能」にするには、signal を受け取って監視します。
code:js
async function myTask(signal) {
signal.throwIfAborted(); // 開始時にチェック
for (const item of items) {
signal.throwIfAborted(); // ループごとにチェック
await process(item);
}
}