BLOG
JavaScriptのfetchにタイムアウトを付ける方法【AbortSignal.timeout】
JavaScriptのfetch()は手軽ですが、何も考えずに使うと、通信が返ってこないときの扱いが曖昧になります。実務のUIでは、読み込み中のまま止まる、再試行できない、エラー内容が分からない、という状態を避けたいところです。
この記事では、AbortSignal.timeout()を使ってfetch()にタイムアウトを付ける基本形をまとめます。
まず押さえること
fetch()はHTTP 404や500だけでは例外にならないresponse.okで成功扱いにしてよいか確認する- タイムアウトは
AbortSignal.timeout()で付けられる - 古い環境も見るなら
AbortControllerとsetTimeoutのフォールバックを用意する
AbortSignal.timeout()を使う
async function fetchJson(url, options = {}) {
const timeout = options.timeout ?? 5000;
const signal = AbortSignal.timeout(timeout);
const response = await fetch(url, {
headers: {
Accept: 'application/json',
...options.headers,
},
signal,
});
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return response.json();
}
try {
const data = await fetchJson('/api/articles', { timeout: 8000 });
console.log(data);
} catch (error) {
if (error.name === 'TimeoutError') {
console.error('通信がタイムアウトしました');
} else if (error.name === 'AbortError') {
console.error('通信が中断されました');
} else {
console.error(error.message);
}
}
古い環境向けのフォールバック
AbortSignal.timeout()は便利ですが、古いブラウザまで強く見る場合は、AbortControllerとsetTimeoutで同じような形を作れます。
async function fetchJsonWithFallbackTimeout(url, options = {}) {
const timeout = options.timeout ?? 5000;
const controller = new AbortController();
const timerId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, {
headers: {
Accept: 'application/json',
...options.headers,
},
signal: controller.signal,
});
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
return response.json();
} finally {
clearTimeout(timerId);
}
}
UI側で分けたい状態
| 状態 | 表示例 |
|---|---|
| loading | 読み込み中のスピナーを出す |
| success | 取得したデータを表示する |
| timeout | 通信が混み合っています。再試行してください。 |
| http error | データの取得に失敗しました。 |
| abort | 通信を中断しました。 |
WordPressや小さなAPIで使うなら
WordPress REST APIや自作APIを読むときも、タイムアウトとresponse.okのチェックを入れておくと、エラーの切り分けが楽になります。特にアクセス解析ダッシュボードやランキング表示のように、画面表示がAPIに依存する機能では最初から入れておきたい処理です。
あわせて読みたい
参考資料
まとめ
fetch()を使うなら、通信成功、HTTPエラー、タイムアウト、中断を分けて扱うだけで、UIの信頼感が上がります。小さな個人開発でも、APIを読む処理には最初からタイムアウトを入れておくのがおすすめです。