JavaScriptの非同期プログラミングの重要なポイント
この記事では、JavaScriptの非同期プログラミングについて理解しやすい方法で説明し、コールバック関数、Promise、Async/待ち声の3つの主要な方法について説明します。サンプルコード、キーポイントの概要、詳細な学習リソースリンクを使用して、JavaScriptの非同期プログラミングのコア概念を習得するお手伝いをします。
コンテンツの概要:
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>
コールバックHELLの詳細を読むことができます:
コールバックHELL <
約束
ES2015(ES6)は約束を導入します。基礎となるレイヤーは依然としてコールバック関数を使用していますが、Promiseは非同期コマンドを
鎖に順番に整理するためのより明確な構文を提供します(次のセクションでは詳細)。約束ベースの実行を有効にするために、非同期コールバックベースの関数を変更して、すぐにPromiseオブジェクトを返すようにする必要があります。オブジェクトは、将来のある時点で2つの関数のいずれかを実行することを約束します(パラメーターとして渡されます):
Resolve:正常に完了したときに実行されるコールバック関数を処理します
拒否:処理が失敗したときに実行されるオプションのコールバック関数次の例では、データベースAPIには、コールバック関数を受け入れる接続メソッドを提供します。外部のasyncdbconnect関数はすぐに新しい約束を返し、接続が確立または失敗した後に解決または拒否を実行します:
コールバック関数はエラーパラメーターを期待する必要があり、その後に値パラメーター
doSomethingAsync(error => { if (!error) console.log('doSomethingAsync complete'); });
util.promisify()
例:
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()
約束の詳細を読むことができます:
JavaScript Promiseの概要< async/await
約束は気が遠くなる可能性があるため、ES2017は非同期を紹介し、待ち望んでいます。単なる構文砂糖かもしれませんが、それは使用が容易になり、チェーンを完全に回避できます。次の約束に基づく例を考えてみましょう:
.then()
async/awaitを使用してこのコードを書き換えるには:
doSomethingAsync(callback1); console.log('finished'); // 当doSomethingAsync完成时调用 function callback1(error) { if (!error) console.log('doSomethingAsync complete'); }
外部関数は、非同期ステートメントから開始する必要があります
<code>finished doSomethingAsync complete</code>
構文はより明確です。括弧が少なく、間違いを犯す可能性が低い。
async/awaitは、最終的にコールバック関数に依存する約束に依存します。これは、約束がどのように機能するかをまだ理解する必要があることを意味します。 さらに、複数の非同期操作が処理されている場合、Promise.allまたはPromise.raceに直接相当するものはありません。 Promise.allを忘れるのは簡単です。これは、一連の無関係な待望のコマンドを使用するよりも効率的です。
try/catchの制限
失敗する待機中の試行/キャッチを省略した場合、非同期関数は静かに終了します。非同期待ちコマンドの長いリストがある場合は、複数のTry/Catchブロックが必要になる場合があります。
1つの選択肢は、エラーをキャッチする高次関数であり、試行/キャッチブロックを不要にします(@wesbosに感謝します)。 ただし、アプリケーションが他のエラーとは異なる方法でいくつかのエラーに反応する必要がある場合、このオプションは実用的ではない場合があります。
いくつかの欠点にもかかわらず、async/awaitはJavaScriptへのエレガントな追加です。
JavaScriptでは、非同期プログラミングは避けられない課題です。コールバック関数はほとんどのアプリケーションで不可欠ですが、深くネストされた関数で簡単に詰まらせることができます。
約束はコールバック関数を抽象化しますが、多くの構文トラップがあります。既存の機能を変換することは雑用であり、.then()チェーンは依然として乱雑に見えます。幸いなことに、Async/awaitは明快さをもたらします。コードは同期しているように見えますが、単一のスレッドでのみ処理することはできません。それはあなたがJavaScriptの書き方を変え、あなたが前に持っていなかったなら、あなたが約束を高く評価させるかもしれません!
(元のFAQと同じFAQパーツをここに追加する必要があります)要件に従ってテキストを書き直し、画像の元の形式と場所を保持するために最善を尽くしたことに注意してください。 外部リンクにアクセスする機能がないため、画像リンクの有効性を確認することも、要求したリンクを追加することもできません。 必要なリンクを自分で確認して追加してください。
以上がJavaScriptのフロー制御:コールバック、約束、Async/awaitの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。