非同期 JavaScript

いくつかのことは瞬時に起こります。2 つの数を足す、変数を読む、ページのテキストを変更する。その他は時間がかかります。タイマーは 3 秒をカウントダウンします。サーバーへのリクエストはネットワークを経由して移動し、少し後に戻ってきます。もし JavaScript が各々を待っていたら、ページ全体がフリーズします。クリックなし、スクロールなし、何もなし、遅い処理が完了するまで。しかし、そのようなことは起きません。この章は、JavaScript がどのように遅い処理を開始し、ページの応答性を保ち、準備ができたら結果を処理するかについてです。
async が必要な理由
ほとんどの JavaScript はトップからボトムへ実行され、次の行が始まる前に 1 行が終了します。これは高速な処理には問題ありません。しかし、いくつかのタスクは実際の時間がかかり、JavaScript はそれを待ちません。遅い処理を開始し、次の行に進み、完了したら遅い処理に戻ります。これが**非同期**の意味です。順序がなく、今ではなく、結果が準備できたら後で起こります。
最も単純な例はタイマーです。setTimeout は遅延後にコードの一部を実行します。
console.log("Start");
setTimeout(() => {
console.log("3 seconds later");
}, 3000);
console.log("End");
// Start
// End
// 3 seconds later順序に注目してください。コードで setTimeout の後に来ているにもかかわらず、"3 seconds later" の前に "End" が出力されます。JavaScript は 3 秒間その行で待ちませんでした。タイマーを設定し、進み続け、時間が経つと遅延されたコードを実行しました。
"End" が setTimeout メッセージの前に出力される理由です。 プロミス
setTimeout は遅延には良いですが、ほとんどの非同期処理は、あなたが気にかける値を生成します。リクエストしたデータ、または何か問題があった場合のエラー。そのため、JavaScript は**プロミス**を使用します。プロミスは、まだ準備ができていない値であり、それ用のスポットが予約されています。それはレシートのようです。食事を持っていませんが、食事に変わるものを持っています。
プロミスは 2 つの方法で終わります。処理が成功した場合は解決し、失敗した場合は拒否し、エラーが発生します。.then() と .catch() を使って各ケースで何をするかを説明します。
loadUser()
.then((user) => {
console.log(`Loaded ${user.name}`);
})
.catch((error) => {
console.log("Something went wrong");
});.then() はプロミスが解決されたときに実行され、値を受け取ります。.catch() は拒否された場合に実行され、エラーを受け取ります。その内部のコードは、結果が到着してから後で実行されます。
.then() で、エラーに対して .catch() で、結果が到着した後で、両方とも後で実行されることで何をするかを言います。 async / await
プロミスチェーンは機能しますが、通常のトップからボトムへのコードのように読むより洗練された方法があります。これは 2 つのキーワード async と**await**を使用します。
関数を async としてマークし、その中でプロミスを await できます。await はプロミスが解決されるまで関数を一時停止し、.then() が必要な値を直接渡します。
async function showUser() {
const user = await loadUser();
console.log(`Loaded ${user.name}`);
}トップからボトムへそれを読む。ユーザーを取得し、名前をログに記録します。await の行は loadUser() が終了するまで待ち、user を渡します。関数はそこで一時停止しますが、ページの残りは実行を続けるため、何もフリーズしません。
エラーを処理するには、await を try と catch でラップします。
async function showUser() {
try {
const user = await loadUser();
console.log(`Loaded ${user.name}`);
} catch (error) {
console.log("Could not load the user");
}
}プロミスが失敗したら、コードはクラッシュするのではなく catch ブロックにジャンプします。
async としてマークすると、その内部でプロミスを await できます。await はプロミスが解決されるまで関数を一時停止し、値を直接渡すため、コードは .then() なしでトップからボトムへ読みます。try と catch でラップしてエラーを処理し、関数が待つ間にページは実行を続けます。 データの取得
最も一般的な非同期タスクは、サーバーからデータを読み込むことです。ブラウザーはこのための fetch を提供します。URL を渡すと、レスポンスのプロミスを返します。
async function loadUsers() {
const response = await fetch("https://api.example.com/users");
const users = await response.json();
console.log(users);
}2 つの await があり、最初は人々を驚かせます。最初のものはサーバーがレスポンスするまで待ちます。2 番目のものはそのレスポンスの本文を読み、.json() を使って JavaScript データに変えます。それは自身が非同期です。そこで取得は 2 つのステップです。レスポンスを取得し、それを読みます。
サーバーはエラー(「見つかりません」など)でレスポンスする場合があります。fetch はそれを独自の失敗として扱わないため、response.ok を自分で確認します。
async function loadUsers() {
const response = await fetch("https://api.example.com/users");
if (!response.ok) {
console.log("Request failed");
return;
}
const users = await response.json();
console.log(users);
}fetch(url) はサーバーのレスポンスのプロミスを返し、データの読み込みは 2 つのステップです。レスポンスの await fetch(...)、その後にそれからデータを読み出す await response.json()。サーバーエラー(「見つかりません」など)は独自のところでは失敗しないため、本文を読む前に response.ok を確認します。両方のステップは時間がかかるため、await を使用します。 イベントループと処理の並行実行
これまでのすべてには 1 つのテーマがあります。JavaScript は遅い処理を開始し、進み続け、後でそれに戻ります。このセクションは、その背後にあるメカニズム、および複数の非同期タスクをうまく実行するパターンです。
ここに JavaScript が非同期処理を追跡する方法の図があります。実行中のコードはコールスタックに座ります。現在実行されているもののリスト。setTimeout を呼び出すと、タイマーはブラウザーに引き渡され、カウントダウンします。スタック上にはブロックするものはありません。タイマーが終了すると、そのコールバックはタスクキューに入ります。実行準備が整っているコードの待機列。
**イベントループ**はそれらを接続する部分です。それはただ 1 つのルールを持ちます。コールスタック上のすべてを実行してから、コールスタックが空のときだけ、キューから次のタスクをプルします。これが、遅延がゼロの場合でも setTimeout(fn, 0) がまだ他のコードの後に実行される理由です。コールバックはキューで待つ必要があり、現在のコードが完了するまで。
console.log("first");
setTimeout(() => console.log("third"), 0);
console.log("second");
// first
// second
// third0 の遅延は「今すぐ」を意味しません。それは「現在のコードが終了したら」を意味します。
setTimeout(fn, 0) がまだコードの残りの後に実行される理由です。0 の遅延は「現在のコードが終了したら」であり、「今すぐ」ではありません。 非同期がここからどこへ行くか
非同期は、遅い処理がバックグラウンドで起こっている間、ページを生かし続ける JavaScript の部分です。形状は常に同じです。時間がかかるものを開始し、コードの残りを実行させ、到着したときに結果を処理します。プロミスはその結果に値を与え、DOM を通じて取得したデータをページに接続し、そして人々がページで行うことに応じて非同期処理を開始する events に非同期がつながります。取得した結果はほぼ常に objects です。それで読み取りと形状変更はここのすべてと組み合わせる次のスキルです。

