以下の内容はhttps://blog.utgw.net/entry/2021/06/03/103006より取得しました。


fetch APIにおけるHTTPリクエストの中断・タイムアウト

AbortControllerを使うことで実現できる。

MDNにも書いてあるけど、以下の操作でfetch APIによるHTTPリクエストを中断できる。

  1. fetch() の第2引数のオブジェクトの signal フィールドに AbortController.signal を渡す
  2. AbortController.abort() を呼ぶ

HTTPリクエストが中断されると、 fetch() が返すPromiseはrejectされる。

ユーザー操作でリクエストを中断する

MDNのサンプルコードデモを参照。

タイムアウトさせる

window.setTimeout() のコールバック関数内で AbortController.abort() を呼ぶとできる。 タイムアウトを過ぎなかったときのために window.clearTimeout() しているけど、いらないかもしれない。

const invokeAPI = async (url) => {
  const controller = new AbortController();
  const timer = window.setTimeout(() => {
    controller.abort();
  }, 1000);
  const response = await fetch(url, {
    signal: controller.signal,
  });
  window.clearTimeout(timer);
  return resp;
};

Promise.race() でタイムアウトさせる場合との違い

Promise.race()fetch() とタイムアウトさせるPromiseを並走させてもタイムアウトは実現できそうに見える。

const timeout = (msec) => {
  return new Promise((_, reject) => {
    window.setTimeout(() => reject('timeout'), msec);
  });
};

await Promise.race([fetch(...), timeout(1000)]);

たしかにタイムアウトできているように見えるけど、AbortControllerを使った場合と違ってHTTPリクエスト自体はキャンセルされない。

一方axiosでは

cancel tokenという仕組みでHTTPリクエストをキャンセルできる。また、リクエストに対してタイムアウトを設定できる

cancel tokenはcancelable PromiseというECMAScriptのproposalに基づいて実装されたらしいけど、このproposalは取り下げられた。Promiseをキャンセルしたいという欲求がありそう。




以上の内容はhttps://blog.utgw.net/entry/2021/06/03/103006より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14