フロントエンドでは、主に2つの方法でリクエストを送信することができます:XHR
とFetch
。XHRは、ええと...かなり昔から存在するAPIです。ただし、設定が煩雑なため、よくjQuery
のgetJSON
、axios
、RxJSのAjaxObservable
などのより高レベルなAPIでラップされて使用されます。
しかし、近年、Promiseの人気が高まるにつれて、Fetch APIがこれらの問題を大幅に改善しました。Promiseを返すだけでなく、操作が容易になるだけでなく、APIも非常にシンプルです。
しかし、それでも致命的な欠点があります。Fetchはリクエストをキャンセルできません。応答が無視されるようにsetTimeoutを使用することはできますが、リクエストは引き続き待機します。XHRでは、XMLHttpRequest.abort
を使用してキャンセルできますが、fetchには類似のAPIがありません。
最近、ついに新しい救世主が登場しました、AbortController
です。
AbortController
インターフェイスの abort() メソッドは、DOMリクエスト(例:Fetchリクエスト)を完了する前に中止します。これにより、fetchリクエスト、応答のBody
の消費、およびストリームを中止できます。
使い方はとても簡単です。
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全体をより便利に使用できるかもしれません。ただし、現時点ではブラウザのサポート状況はまだ十分ではありません。