今回の仕上がり
「もう一度取得する」ボタンを押したのに、すぐ中止扱いになる場合があります。通信先だけでなく、前の操作で中止したsignalを渡していないかを確認します。このサンプルでは同じsample.jsonを読み、使うsignalだけを変えます。外部サービスや課金APIへの通信はありません。

中止済みと新規を比べる
- 「中止済みsignalで取得」を押します。aborted=trueと失敗:AbortErrorが出ます。
- 同じボタンをもう一度押します。中止済みの状態は戻らず、同じ結果になります。
- 「新しいsignalで取得」を押します。aborted=falseの後に「成功:サンプルを読み込みました」が出ます。
- 「ログを消す」は表示だけを消します。中止済みcontrollerを初期化する操作ではありません。
const used = new AbortController();
used.abort();
// 中止済みのsignalでの取得は失敗する
await fetch("sample.json", { signal: used.signal });
// 別の処理として再試行するときは新しく作る
const fresh = new AbortController();
await fetch("sample.json", { signal: fresh.signal });上のコードは2つのケースを並べた抜粋です。最初のawaitが失敗するため、そのまま一続きに実行すると後ろへ進みません。配布HTMLでは各ボタンの処理をtry/catchで分けています。MDNのAbortSignalの説明でも、中止後の同じsignalを渡すfetchは直ちに拒否されることを確認できます。
実際のアプリでの確認範囲
この比較は取得前に中止したsignalの再利用を扱っています。大きなデータを通信の途中で止める速度や、サーバー側の処理が停止したかは測っていません。ブラウザで中止できたことを、サーバーでの課金や処理が必ず取り消された証拠にはできません。
エラー名の確認も分けます。ここでは引数なしのabort()を使ってAbortErrorを確認しました。独自の中止理由やタイムアウトを加えたアプリでは、同じ名前だけで全失敗を分類できるとは限りません。HTTP 404の扱いはHTTPとJSONを分ける実験で確認できます。
2026年10月19日、PCと375px幅、ライト・ダークで操作を確認しました。HTMLとJSONは編集部の自作・CC0です。ZIPを展開して新規取得を試す場合は、ファイルをHTTPで配信して開いてください。fileから直接開く場合の通信制限はこの比較の対象外です。全ブラウザ、スマホ実機、外部APIの中止動作は未確認です。