2番目のコードで、res とjson と json.nameそれぞれの内容を確認するため下記のように変えてみます。
js
1async function access(url) {
2 const res = await fetch(url);
3 console.log('res: ' + res); // 追加
4
5 const json = res.json();
6 console.log('json: ' + json); // 修正
7 console.log('json.name: ' + json.name); // 追加
8}
9const url = 'https://jsonplaceholder.typicode.com/users/1';
10access(url);
として実行すると
> "res: [object Response]"
> "json: [object Promise]"
> "json.name: undefined"
と表示されます。
つまり、どうやら
・res は (undefined ではなく)Response オブジェクト
・json は Promise オブジェクト
・json.name は(当初確認できたように)undefined
らしい、ということが分かります。
まとめると、「『fetch(url)』の結果が返ってくるまで待っていて、
resに結果が入ってから次の『res.json()』が実行される」、という質問者さんの認識はほぼ合っていますが、
実行したときの結果が違います。
なぜ違いが出るのか。
① 2番目のコードの処理の流れ
const res = await fetch(url);
まずこれによりres は Responseオブジェクトに紐つけられます。
そして、次:
Responseオブジェクトのjson() メソッドは Promiseを返します。
したがって、res.json() の戻り値は Promise オブジェクトとなるため、左辺の変数 json は Promise オブジェクトに紐付けられることになります。
しかし、Promise オブジェクト自体には name キーがないので
次の
を実行すると undefined と出力されてしまいます。
② 最初のコードの処理の流れ
const res = await fetch(url);
までは①と同じです。
変数res には Response オブジェクトが紐付けられます。
次の行:
js
1const json = await res.json();
2console.log(json.name);
async/await は Promiseのシンタックスシュガーですので、この2行は
js
1res.json().then(json => console.log(json.name));
とほぼ同じです。
これが実行されると、thenの後の引数「json」には、Promise の解決後のデータ(レスポンスの本文のテキストを JSON として解釈した結果データ)が格納されます。
具体的には、urlで指定したエンドポイントからのレスポンスJSONです。
これは name キーを持っていますので、期待する出力となります。
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
2022/06/04 00:35
2022/06/04 01:00 編集
2022/06/04 13:57