· 2分で読了

新しいリクエストキャンセルの方法 - 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 AbortController interface aborts a DOM request (e.g. a Fetch request) before it has completed. This is able to abort fetch requests, consumption of any response Body, 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全体をもっと扱いやすくできるかもしれない。ただし、現時点でのブラウザのサポート状況はまだ十分とは言えない。

関連記事

他のトピックを探索