ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScriptのフロー制御:コールバック、約束、Async/await

JavaScriptのフロー制御:コールバック、約束、Async/await

Lisa Kudrow
リリース: 2025-02-11 08:26:16
オリジナル
156 人が閲覧しました

Flow Control in JavaScript: Callbacks, Promises, async/await

JavaScriptの非同期プログラミングの重要なポイント

この記事では、JavaScriptの非同期プログラミングについて理解しやすい方法で説明し、コールバック関数、Promise、Async/待ち声の3つの主要な方法について説明します。サンプルコード、キーポイントの概要、詳細な学習リソースリンクを使用して、JavaScriptの非同期プログラミングのコア概念を習得するお手伝いをします。

コンテンツの概要:

  1. 単一スレッド処理
  2. コールバック関数を使用して、非同期操作を実装します
    • コールバックHELL
  3. 約束
    • Asyncチェーンコール
    • 約束の未来?
  4. async/await
    • 約束のアップグレード
    • try/catchの制限
  5. JavaScript非同期プログラミングジャーニー
JavaScriptのasync機能

async javascriptは、しばしば「非同期」言語と呼ばれます。それはどういう意味ですか?開発にどのように影響しますか?近年、その方法でどのような変化が発生しましたか?

次のコードを検討してください:

ほとんどの言語は、すべての行のコードを同期して処理します。最初の行は結果を実行して返します。2番目の行は、最初の行にかかる時間に関係なく、最初の行が完了した後にのみ実行されます。
result1 = doSomething1();
result2 = doSomething2(result1);
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

シングルスレッド処理

JavaScriptは単一のスレッドで実行されます。 [ブラウザ]タブで実行されると、他のすべての操作が停止します。これは、1つのスレッドが別のURLにリダイレクトされ、別のスレッドが子ノードを接続しようとする場合、ページDOMの変更が危険になるため、これが必要です。

ユーザーは、小さなブロックで処理が迅速に進行するため、これに気付くことはめったにありません。たとえば、JavaScriptはボタンクリックを検出し、計算を実行し、DOMを更新します。完了すると、ブラウザはキューで次のアイテムを処理できます。

(注:PHPなどの他の言語も単一のスレッドを使用しますが、マルチスレッドサーバー(Apacheなど)で管理できます。同じPHPページの2つの同時リクエストは2つのスレッドを起動して実行できます。 PHPは隔離インスタンスを実行します

コールバック関数を使用して、非同期操作を実装

単一のスレッドは問題をもたらします。 JavaScriptは、サーバー上のブラウザまたはデータベース操作からのAJAX要求など、「遅い」プロセスを呼び出すとどうなりますか?この操作には数秒または数分かかる場合があります。応答を待っている間、ブラウザはロックされます。サーバーでは、node.jsアプリケーションはユーザー要求をさらに処理できません。 ソリューションは非同期処理です。完了を待つ代わりに、結果の準備ができたら別の関数を呼び出すプロセスを指示します。これはコールバック関数と呼ばれ、非同期関数の引数として渡されます。

例:

dosomethingasync関数は、コールバック関数を引数として受け入れます(関数への参照のみを渡すため、オーバーヘッドが小さい)。将来のある時点でcallback1が実行されることを知っていることは、どれほどかかるかは関係ありません。コンソールが表示されます:

result1 = doSomething1();
result2 = doSomething2(result1);
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

コールバック関数の詳細を読むことができます:JavaScriptコールバック関数<

コールバックHELL <

通常、コールバック関数は1つの非同期関数のみで呼ばれます。したがって、簡潔な匿名のインライン関数を使用できます。 一連の非同期呼び出しは、コールバック関数をネストすることで完了することができます。たとえば、

残念ながら、これはコールバックHell-独自のWebページさえある悪名高いコンセプトを紹介します。コードは読みにくく、ロジックのエラー処理を追加すると悪化します。
doSomethingAsync(callback1);
console.log('finished');

// 当doSomethingAsync完成时调用
function callback1(error) {
  if (!error) console.log('doSomethingAsync complete');
}
ログイン後にコピー
ログイン後にコピー

コールバックヘルは、クライアントエンコーディングでは比較的まれです。 AJAXコールを作成し、DOMを更新し、アニメーションが完了するのを待つ場合、2〜3層になる可能性がありますが、通常は管理可能です。

<code>finished
doSomethingAsync complete</code>
ログイン後にコピー
ログイン後にコピー
オペレーティングシステムまたはサーバープロセスの場合、状況は異なります。 node.js API呼び出しは、ファイルのアップロードを受信し、複数のデータベーステーブルを更新し、ログを書き込み、応答を送信する前にさらにAPI呼び出しを行う場合があります。

コールバックHELLの詳細を読むことができます:

コールバックHELL <

約束

ES2015(ES6)は約束を導入します。基礎となるレイヤーは依然としてコールバック関数を使用していますが、Promiseは非同期コマンドを

鎖に順番に整理するためのより明確な構文を提供します(次のセクションでは詳細)。

約束ベースの実行を有効にするために、非同期コールバックベースの関数を変更して、すぐにPromiseオブジェクトを返すようにする必要があります。オブジェクトは、将来のある時点で2つの関数のいずれかを実行することを約束します(パラメーターとして渡されます):

Resolve:正常に完了したときに実行されるコールバック関数を処理します

拒否:処理が失敗したときに実行されるオプションのコールバック関数

次の例では、データベースAPIには、コールバック関数を受け入れる接続メソッドを提供します。外部のasyncdbconnect関数はすぐに新しい約束を返し、接続が確立または失敗した後に解決または拒否を実行します:

  • node.js 8.0は、コールバックベースの関数を約束ベースの代替案に変換するための
  • ユーティリティを提供します。 2つの条件があります:
非同期関数の最後のパラメーターとしてコールバックを渡す必要があります

コールバック関数はエラーパラメーターを期待する必要があり、その後に値パラメーター
doSomethingAsync(error => {
  if (!error) console.log('doSomethingAsync complete');
});
ログイン後にコピー
が続きます。

util.promisify()例:

  • asyncチェーンコール
  • 約束を返すものはすべて、
メソッドで定義された一連の非同期関数呼び出しを開始できます。各関数は、以前の解決からの結果を受け取ります:

async1((err, res) => {
  if (!err) async2(res, (err, res) => {
    if (!err) async3(res, (err, res) => {
      console.log('async1, async2, async3 complete.');
    });
  });
});
ログイン後にコピー
同期関数は、

ブロックで実行することもできます。返品値は次の(ある場合)に渡されます。

メソッドは、以前の拒否がトリガーされたときに呼び出される関数を定義します。現時点では、.then()メソッドは再び実行されます。チェーン全体で複数の

メソッドを使用して、異なるエラーをキャッチできます。
const db = require('database');

// 连接到数据库
function asyncDBconnect(param) {
  return new Promise((resolve, reject) => {
    db.connect(param, (err, connection) => {
      if (err) reject(err);
      else resolve(connection);
    });
  });
}
ログイン後にコピー

ES2018は、結果に関係なく最終的なロジックを実行するA .finally()メソッドを導入します。たとえば、クリーンアップ、データベース接続の閉鎖など。すべての最新のブラウザでサポートされています:

result1 = doSomething1();
result2 = doSomething2(result1);
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

約束の未来?

約束はコールバックHellを減らしますが、それ自体の問題ももたらします。

チュートリアルでは、約束チェーン全体が非同期であることについては言及していません。一連の約束を使用する関数は、独自の約束を返すか、最終.then()、または.catch()メソッドでコールバック関数を実行する必要があります。 .finally()

Promiseの構文は通常、コールバック関数よりも複雑であり、多くのエラーが発生しやすい場所があり、デバッグも面倒です。ただし、基本を学ぶことは重要です。

約束の詳細を読むことができます:

JavaScript Promiseの概要< async/await

約束は気が遠くなる可能性があるため、ES2017は非同期を紹介し、待ち望んでいます。単なる構文砂糖かもしれませんが、それは使用が容易になり、チェーンを完全に回避できます。次の約束に基づく例を考えてみましょう:

.then()async/awaitを使用してこのコードを書き換えるには:

doSomethingAsync(callback1);
console.log('finished');

// 当doSomethingAsync完成时调用
function callback1(error) {
  if (!error) console.log('doSomethingAsync complete');
}
ログイン後にコピー
ログイン後にコピー

外部関数は、非同期ステートメントから開始する必要があります

    非同期、約束ベースの関数への呼び出しは、次のコマンドを実行する前に処理が完了することを確認するために待って開始する必要があります
  • 待ち行列JavaScriptで単一スレッド処理を行わずに、各コールの外観を同期させます。さらに、Async関数は常に約束を返すため、他の非同期関数によって順番に呼び出されます。
<code>finished
doSomethingAsync complete</code>
ログイン後にコピー
ログイン後にコピー
async/awaitコードは短くないかもしれませんが、多くの利点があります:

構文はより明確です。括弧が少なく、間違いを犯す可能性が低い。

    デバッグは簡単です。ブレークポイントは、任意の任意のステートメントに設定できます。
  • エラー処理の方が良いです。同期コードと同様に、Try/Catchブロックを使用できます。
  • 良いサポート。すべての最新のブラウザとノード7.6に実装されています。
  • 言い換えれば、すべてが完全ではないわけではありません...
約束のアップグレード

async/awaitは、最終的にコールバック関数に依存する約束に依存します。これは、約束がどのように機能するかをまだ理解する必要があることを意味します。 さらに、複数の非同期操作が処理されている場合、Promise.allまたはPromise.raceに直接相当するものはありません。 Promise.allを忘れるのは簡単です。これは、一連の無関係な待望のコマンドを使用するよりも効率的です。

try/catchの制限

失敗する待機中の試行/キャッチを省略した場合、非同期関数は静かに終了します。非同期待ちコマンドの長いリストがある場合は、複数のTry/Catchブロックが必要になる場合があります。

1つの選択肢は、エラーをキャッチする高次関数であり、試行/キャッチブロックを不要にします(@wesbosに感謝します)。 ただし、アプリケーションが他のエラーとは異なる方法でいくつかのエラーに反応する必要がある場合、このオプションは実用的ではない場合があります。

いくつかの欠点にもかかわらず、async/awaitはJavaScriptへのエレガントな追加です。

javascript async/await ing getting guid JavaScript非同期プログラミングジャーニー

JavaScriptでは、非同期プログラミングは避けられない課題です。コールバック関数はほとんどのアプリケーションで不可欠ですが、深くネストされた関数で簡単に詰まらせることができます。

約束はコールバック関数を抽象化しますが、多くの構文トラップがあります。既存の機能を変換することは雑用であり、.then()チェーンは依然として乱雑に見えます。

幸いなことに、Async/awaitは明快さをもたらします。コードは同期しているように見えますが、単一のスレッドでのみ処理することはできません。それはあなたがJavaScriptの書き方を変え、あなたが前に持っていなかったなら、あなたが約束を高く評価させるかもしれません!

(元のFAQと同じFAQパーツをここに追加する必要があります)要件に従ってテキストを書き直し、画像の元の形式と場所を保持するために最善を尽くしたことに注意してください。 外部リンクにアクセスする機能がないため、画像リンクの有効性を確認することも、要求したリンクを追加することもできません。 必要なリンクを自分で確認して追加してください。

以上がJavaScriptのフロー制御:コールバック、約束、Async/awaitの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート