fetch()
- ネットワーク越しにデータを取得するためのものです。
- Webサイトからデータを取得したり、APIを使ってサーバーとやり取りしたりする際に使用されます。
-
fetch()は非同期処理になっていて、これが実行された時点でバックグラウンドで通信が開始されるという仕組みになっています。
非同期処理とは、「時間がかかるかもしれない処理」を、その完了を待たずにバックグラウンドで進めながら次の処理に進める仕組みのことです。
- そのバックグラウンドで行われる非同期処理が今どういう状態なのかは、
fetch()の返り値で知ることができます。- 返り値ですが
Promiseと呼ばれる種類のオブジェクトで、非同期処理の状態に応じて値が変わる、特殊なオブジェクトになっています。
- 返り値ですが
Promise
fetch()を実行した時に、非同期処理が現在どのような状態なのかを表すオブジェクトです。
Promiseはライフサイクルにおいて、以下のいずれかの状態にあります。
Pending (保留中):
- 初期状態。非同期処理がまだ完了していない、またはまだ開始もされていない状態です。
- 注文した料理がまだ作られている途中。
Fulfilled (解決済み):
- 非同期処理が成功して完了した状態です。結果の値(料理)が利用可能です。
-
Promise.prototype.then()メソッドで登録されたコールバック関数が実行されます。 - 料理が完成し、受け取った状態。
Rejected (拒否済み):
- 非同期処理が失敗して完了した状態です。エラー理由(材料切れ)が利用可能です。
-
Promise.prototype.catch()またはPromise.prototype.then(null, onRejected)で登録されたコールバック関数が実行されます。 - 料理が作れず、その理由を伝えられた状態。
非同期処理の書き方
非同期処理の書き方は、下記の2つがあります。
-
await/asyncを使う書き方 -
.then()/.catch()を使う書き方
それぞれ見ていきましょう。
await/ async
-
awaitとは、「バックグラウンドで非同期処理を実行させ、その結果(戻り値)が返ってくるまで、async関数内のそれ以降のコードの実行を一時停止して待ってくれる」ものです。- 他のコードは走り続けることができるので、UIがフリーズしたり、Webページが応答しなくなったりするのを防ぎます。
-
Promiseが解決したら、async関数内のそれ以降のコードの実行を再開します。
基本構文
const showUsers = async () => {
try {
const response = await fetch(
'URL'
);
const users = await response.json();
console.log(users);
} catch (err) {
console.log('Error! ');
console.log('Errorlog' + err);
}
};
-
awaitが使われている関数には、必ず先頭にasyncをつけます。 awaitでの実行結果がエラーなく返ってきた場合、responseとして受け取ることができます。-
try文で実行中、途中でエラーとなった場合はcatch文の処理へとうつります。
.then()/.catch()
function showUsers() fetch('URL')
.then((res) => {
return res.json();
})
.then((users) => {
console.log(users);
})
.catch((err) => {
console.log('Error! ');
console.log('Errorlog' + err);
});
}
- 一つ目の
thenでresponseを受け取ります。うまく行った場合次のthenに値を返します。
値を渡すためにreturnとする必要があります。
- 二つ目の
thenでresponse結果を改めて受け取り、表示します。 -
catch()で続けてかけば、エラーの場合の処理を定義することができます。
なぜ res.json() を returnして次の .then()に渡すのか?
こちらの疑問は、awaitでのresponse.json();になぜawaitをつける必要があるのか?にも当てはまります。
1.fetch()が返す最初のPromiseは「HTTPレスポンス」オブジェクト
- fetch('URL') が解決すると、まず
Responseオブジェクトが返されます。 - この
Responseオブジェクトには、HTTPステータスコード(例: 200 OK)、ヘッダーなどのメタデータが含まれますが、肝心の実際のデータ(JSONデータやテキストデータなど)はまだ読み込まれていません。
2.res.json()は「レスポンスボディの読み込みとパース」を非同期で行う
-
res.json()というメソッドは、Responseオブジェクトのボディ部分(中身のデータ)を読み込み、それをJSON形式として解析するための非同期処理です。 - この
res.json()自体も、別の新しい Promise を返します。 - この新しい Promise は、「ボディの読み込みとJSON解析が完了したら解決する」という約束を持っています。
3.Promiseチェーンのルール
-
.then()の中でPromiseをreturnすると、次の.then()はその返されたPromiseが解決されるまで「待機」します。 - そして、返された
Promiseが解決したとき、その解決値が次の.then()の引数として渡されます。
既出になりますがawaitは、その結果(戻り値)が返ってくるまで、async関数内のそれ以降のコードの実行を一時停止して待ってくれる」ものなので順番に実行することができます。