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
関数内のそれ以降のコードの実行を一時停止して待ってくれる」ものなので順番に実行することができます。