- 公開日
JavaScriptのXHRの送り方いろいろ: XMLHttpRequest, fetch, async/await
JavaScriptのXHR(XMLHttpRequest)の送り方は1つだけではありません。モダンなXHRに向けてそれぞれのHTTPリクエストの送り方を比較・検討してみます。
前提
- jQuery, superagent, axiosなどのAJAX系ライブラリは使用しないこととする。
- 検証に使うブラウザは最新版のChrome (現在はVersion56.0)
- 今回リクエストを送る先は仮想的に下記のURLとする
var url = "https://your.domain.net/"
1. XMLHttpRequest
さぁ,まずは古き良きXMLHttpRequest。ローレベルなAPIでAJAX処理が書きにくいのですが、歴史がある分多くのブラウザで動作します。
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = function() {
console.log(xhr.status);
};
xhr.onerror = function() {
console.log("error!");
};
xhr.send();
Chrome Dev Toolのコンソールで動かしてみましょう。
モダンな書き方にしてみよう!
このまま次のXHRに進んでも良いですがせっかくなので上記のコードをもう少しモダンにしてみます。
今回は下記の2つの書き方を導入します。
- const = 定数
- Arrow function = アロー関数
上記の2つで1のXMLHttpRequestのコードを書き直すとこのようになります。
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
console.log(xhr.status);
};
xhr.onerror = () => {
console.log("error!");
};
xhr.send();
var
はconst
に、function
は=>
へと変更しています。わかりやすくなってスッキリしましたね。
この書き方でも動くかChrome Dev Toolのコンソールで動かしてみましょう。
でした。
2. fetch API
次はfetch
APIを使ってXHRしてみましょう。ちなみにfetch APIはChrome Version 42よりサポートされています。
fetch(url).then((response) => {
console.log(response.status);
}).catch(() => {
console.log("error caught!");
});
コードとしてはurlをfetch
してthen
, catch
をチェインさせてそれぞれの処理内容を書いていくというものになります。
Chrome Dev Toolコンソールで動かした結果。
fetch
はPromiseを返す点がポイントですね。
3. fetch + async/await
最後のXHRはasync/awaitになります。Chrome55からのサポートなので最近追加された機能ということになります。
さきほどのfetch
のコードをasync/awaitの機能を使って書き換えてみましょう。
(async() => {
try {
const response = await fetch(url);
console.log(response.status);
} catch (e) {
console.log("error!")
}
})();
ポイントとしては async
を使ってまず無名関数を作ります。これでその関数内にawait
を使う準備ができました。awaitはPromiseが返されるのを待機するので、先程のPromiseを返すfetch
関数の手前にawait
を宣言します。これでfetch
関数はthen
でコールバックをチェインする必要がなくなり、response
変数にダイレクトに結果が代入されます。エラー処理に関してはtryで処理内容を囲み、catchでエラーを補足します。
コンソールで動かしてみた結果は下記の通り。
結論
結論としては現時点では3つめのfetch+async/awaitな書き方が最もモダンな書き方となります。
3の書き方でなにが嬉しいかというと:
- 非同期処理でありがちなコールバック地獄からの解放
- 同期的なコードで書けるので書きやすい・読みやすい
- try~catch節を用いているのでエラー処理の見通しが良い
このあたりでしょうか。
まだasync/awaitシンタックスはECMAScript 2017のDraftな仕様というステータスであり現時点でIEはサポートしていない書き方です。なので多くの人が触る環境下のコードベースにおける導入は厳しいですが、これらが使える利用環境を限定できるのであれば積極的に使っていきたい書き方ですね。
(おまけ)babelで使う場合
babel で async/await のシンタックス使いたい場合はbabel-plugin-syntax-async-functions
を使うことになります。
Syntax async functions · Babel