新しいリクエストキャンセルの方法 - AbortController
フロントエンドにおいて、リクエストを送信する方法は主に2つある。XHRとFetchだ。XHRは、うーん…、かなり昔からあるAPIだ。ただ設定がとても面倒なため、jQueryのgetJSON、axios、RxJSのAjaxObservableなどの、より高レイヤーなAPIにラップされて使われることが多かった。
一方で、近年Promiseの普及に伴って広まったFetch APIは、これらの問題を大幅に改善してくれる。戻り値がPromiseで扱いやすいだけでなく、API自体もかなりシンプルだ。
だがそれでもなお、致命的な欠点が1つある。Fetchはリクエストをキャンセルできないのだ。setTimeoutを使ってレスポンスを無視することはできるものの、リクエスト自体は待ち続けることになる。XHRではXMLHttpRequest.abortを使ってキャンセルできたが、fetchには似たようなAPIが存在しなかった。
そして最近になって!ついに新たな救世主、AbortControllerが登場した。
The abort() method of the
AbortControllerinterface aborts a DOM request (e.g. a Fetch request) before it has completed. This is able to abort fetch requests, consumption of any responseBody, and streams.
使い方はとてもシンプルだ。
const abortController = new AbortController()
const signal = abortController.signal
あとはこのsignalをfetchに渡すだけでいい。
fetch("/long-running", { signal: signal })
abortController.abortを呼び出すと、signalを経由してfetch側に伝わる。signalを受け取った時点でまだリクエストが完了していなければ、そのリクエストはキャンセルされる。
fetch("/long-running", { signal: signal })
setTimeout(() => abortController.abort(), 5000)
5秒以内にリクエストが完了しなければ、キャンセルされるというわけだ。
RxJSと組み合わせてラップすれば、API全体をもっと扱いやすくできるかもしれない。ただし、現時点でのブラウザのサポート状況はまだ十分とは言えない。
関連記事
- Three.js で僕の部屋を表現する 僕が React Three Fiber を使って実際の自分の部屋をブラウザ上に再現し、実世界のオブジェクトを目録に見立て、空間の記憶を通してここ数年の生活と仕事について語った話。
- フロントエンドで画像を扱う際に注意すべきこと Jake Archibaldの記事を起点に、現代のレスポンシブ画像の書き方を整理する。なぜwidth/heightを付ける必要があるのか、CSSのaspect-ratioはいつ使うべきか、AVIFとWebPの選び方、そしてpicture/source/srcsetを使ったモバイル向け画像の切り替えについて。
- CSS field-sizing — たった1行のCSSでフォーム要素を自動リサイズする かつてtextareaの自動高さ調整は、JavaScriptでscrollHeightを監視するしかなかった。しかしCSSのfield-sizing: contentなら、わずか1行で代替でき、textarea、input、selectに対応している。本記事では従来のやり方のペインポイントと、field-sizingの使い方をまとめる。
- リンクの下線をもっと見栄え良くする:text-underline-offset デフォルトでは下線と文字が近すぎて、このスタイルを好まないデザイナーもいるし、僕自身もあまり綺麗ではないと感じていた。