検索
ホームページウェブフロントエンドjsチュートリアルNodejs 非同期プログラミングの詳細な説明_node.js

現在の要件には多数の非同期操作が含まれており、実際のページはますます単一ページ アプリケーションに傾いています。将来的には、backbone、angular、knockout などのフレームワークを使用する可能性がありますが、最初に直面する必要があるのは非同期プログラミングに関する問題です。ノードの台頭により、非同期プログラミングが非常にホットなトピックになっています。一定期間の学習と実践の後、非同期プログラミングの詳細がいくつかまとめられます。

1. 非同期プログラミングの分類

非同期の問題を解決する方法には、一般に、ダイレクト コールバック、パブリッシュ/サブスクライブ モード (イベント モード)、非同期ライブラリ制御ライブラリ (async、when など)、Promise、ジェネレーターなどが含まれます。
1.1 コールバック関数

コールバック関数は、非同期の問題を解決するためによく使用されるメソッドであり、よく参照され、理解しやすく、ライブラリや関数に実装するのが非常に簡単です。これは、非同期プログラミングを使用するときに誰もがよく使用する方法でもあります。

しかし、コールバック関数メソッドには次の問題があります:

1. 邪悪な入れ子ピラミッドを形成する可能性があり、コードが読みにくくなります。

2. 対応できるコールバック関数は 1 つだけですが、これは多くのシナリオで制限となります。

1.2 パブ/サブモード (イベント)

このモードはイベント モードとも呼ばれ、コールバック関数のイベント化であり、jQuery などのライブラリで非常に一般的です。

イベント発行サブスクライバー モデル自体には同期呼び出しと非同期呼び出しの問題はありませんが、ノードでは、エミット呼び出しはイベント ループと非同期でトリガーされることがほとんどです。このモードは、ビジネス ロジックを分離するためによく使用されます。イベント発行者は、登録されたコールバック関数を意識する必要がなく、メッセージを通じてデータを柔軟に転送できます。

このモードの利点は次のとおりです: 1. 理解しやすい; 2. 1 つのコールバック関数に限定されなくなりました。

欠点: 1. クラス ライブラリを使用する必要がある; 2. イベントとコールバック関数の順序が非常に重要

コードをコピーします コードは次のとおりです:
var img = document.querySelect(#id);
img.addEventListener('load', function() {
// 画像の読み込みが完了しました

});
img.addEventListener('error', function() {
// 問題が発生しました
……
});

上記のコードには 2 つの問題があります:

a. img は実際にはロードされており、ロード コールバック関数はこの時点でのみバインドされているため、コールバックは実行されませんが、対応するコールバック関数が実行されることを期待します。

コードをコピーします コードは次のとおりです:
var img = document.querySelect(#id);
関数load() {
...
}
if(img.complete) {
ロード();
} else {
img.addEventListener('load',load);
}
img.addEventListener('error', function() {
// 問題が発生しました
……
});

b. 例外をうまく処理できない

結論: イベント メカニズムは、同じオブジェクトで繰り返し発生する処理に最適です。コールバック関数がバインドされる前にイベントの発生を考慮する必要はありません。

1.3 非同期制御ライブラリ

現在の非同期ライブラリには主に Q、when.js、win.js、RSVP.js などが含まれます。

これらのライブラリの特徴は、コードが直線的であり、自然な習慣に沿って上から下に記述できることです。

欠点は、スタイルが異なるため読みにくくなり、学習コストが増加することです。

1.4 約束

Promise は中国語に訳すと約束となりますが、私の個人的な理解では、非同期完了後に外部の結果 (成功または失敗) を与え、その結果が変わらないことを約束します。言い換えれば、Promise は操作の最終的な戻り値を反映します (Promise は、操作の 1 回の完了から返される最終的な値を表します)。現在、Promise は ES6 仕様に導入されており、Chrome や Firefox などの先進的なブラウザはこのネイティブ メソッドを内部的に実装しているため、非常に使いやすくなっています。

Promise の特徴を次の側面から分析してみましょう:

1.4.1 ステータス

保留、履行、および拒否の 3 つの状態が含まれます。3 つの状態の間で発生できる遷移は 2 つだけ (保留中 ---> 履行、保留中 --> 拒否)、状態遷移は 1 回だけ発生します。

1.4.2 メソッド

then メソッドは、非同期イベントの完了後のコールバック関数を指定するために使用されます。

このメソッドは、Promise を魔法に満ちたものにする、Promise の魂のメソッドと言えます。以下に示すような具体的な症状がいくつかあります:

a) then メソッドは Promise を返します。これにより、複数の非同期操作のシリアル操作が可能になります。

上の図の黄色の丸 1 の値の処理については、Promise のより複雑な部分であり、値の処理は Promise オブジェクトと非 Promise オブジェクトの 2 つの状況に分かれています。

value が Promise 型でない場合は、2 番目の Promise のリゾルブのパラメータ値として value を使用するだけで、Promise 型の場合は、promise2 のステータスとパラメータは完全に value によって決定されると考えることができます。 promsie2 は完全に value の操り人形であり、promise2 は異なる非同期のものを接続する単なるブリッジです。

コードをコピー コードは次のとおりです:

Promise.prototype.then = function(onFulfilled, onRejected) {
    return new Promise(function(resolve, respect) { //此处的Promise标注はpromise2
        ハンドル({
            onFulfilled: onFulfilled、
            onRejected: onRejected,
            解決: 解決、
            拒否: 拒否
        })
    });
}
関数ハンドル(遅延) {
    var handleFn;
    if(状態 === '満たされた') {
        handleFn = deferred.onFulfilled;
    } else if(state === '拒否') {
        handleFn = deferred.onRejected;
    }
    var ret = handleFn(値);
    deferred.resolve(ret);                           //注意、今回の解決策はpromise2の解決策です
}
function resolve(val) {
    if(val && typeof val.then === '関数') {
        val.then(解決);                           // val が promise オブジェクトまたは promise オブジェクトの場合、promise2 の状態は val によって完全に決定されます
        戻る;
    }
    if(callback) { // コールバックは指定された回调関数
        コールバック(val);
    }
}

b) 複数の異なるブロック間の変換が実行されます。

异步中に呼び出し可能なオブジェクトが存在します。これは、then メソッドを持つオブジェクトを意味します。ただ 1 つのオブジェクトが then メソッドを持ち、それに対して実行できるオブジェクトを指します。例:

复制代 代码如下:

var deferred = $('aa.ajax');      // !!deferred.then === true
var P = Promise.resolve(deferred);
p.then(……)

1.4.3 commonJS Promise/A规范

現在、Promise の規定に関しては Promise/A および Promise/A の規定が存在しており、これは Promise の実現が複雑であることを示しています。

复制代 代码如下:
then(fulfilledHandler、rejectedHandler、progressHandler)

1.4.4 注意事项

Promise の 1 つの戻り関数は値を共有しており、結果処理で値がパラメータとして渡される対応する戻り関数です。値がオブジェクトの場合、簡単に変更できる値は無視されます。

var p = Promise.resolve({x: 1});
p.then(function(val) {
    console.log('最初のコールバック: ' val.x );
});
p.then(function(val) {
    console.log('2 番目のコールバック: ' val.x)
})
// 最初のコールバック: 1
// 2 番目のコールバック: 2

1.5 ジェネレーター

上記のメソッドはすべて、非同期操作を完了するためのコールバック関数に基づいています。これらはコールバック関数のカプセル化にすぎません。ジェネレーターは ES6 で提案されており、非同期操作を解決する方法が追加され、コールバック関数に依存しなくなります。

Generator の最大の特徴は、関数を一時停止および再開できることです。この機能は、非同期操作を解決するのに非常に役立ちます。 Generator の一時停止と Promise の例外処理を組み合わせると、非同期プログラミングの問題をよりエレガントに解決できます。特定の実装リファレンス: Kyle Simpson

2. 非同期プログラミングの問題

2.1 例外処理

a) 非同期イベントには、非同期リクエストの発行と結果処理の 2 つのリンクが含まれます。これらの 2 つのリンクは、イベント ループを通じて接続されます。 Try catch を使用して例外をキャプチャする場合は、例外を個別にキャプチャする必要があります。

コードをコピーします コードは次のとおりです:

{
を試してください asyncEvent(コールバック); } キャッチ(エラー) {

}

上記のコードはコールバックで例外をキャプチャできませんが、リクエスト プロセスでのみ例外を取得できます。これにより問題が発生します。リクエストの発行とリクエストの処理が 2 人で完了した場合、例外を処理するときに問題が発生しますか?

b) Promise は例外配信を実装します。これによりいくつかの利点がもたらされ、コードが実際のプロジェクトでブロックされないことが保証されます。ただし、非同期イベントが多数ある場合、どの非同期イベントが例外を引き起こしたかを見つけるのは簡単ではありません。

コードをコピーします コードは次のとおりです:
// シナリオの説明: CRM に競合情報を含む価格アラーム情報を表示します。ただし、競合情報の取得には時間がかかります。クエリの遅延を避けるために、バックエンドはレコードを 2 つの部分に分割し、別々に取得します。
// ステップ 1: 競合情報に加えて、価格アラーム情報を取得します
function getPriceAlarmData() {
新しい Promise(function(resolve) を返す {
Y.io(url, {
メソッド: 'get',
データ: params,
on: function() {
成功: function(id, data) {
解決(アラームデータ);
}
}
});
});
}
// アラーム情報取得後、大会情報を取得
getPriceAlarmData().then(function(data) {
//データレンダリング(競技情報を除く)
レンダリング(データ);
新しい Promise(function(resolve) を返す {
Y.io(url, {
メソッド: 'get',
データ: {alarmList: data},
on: function() {
成功: function(id, compData) {
resolve(compData);
}
}
});
});
}) // すべてのデータを取得したら、競合情報をレンダリングします
.then(関数(データ) {
// コンテスト情報をレンダリングします
レンダリング(データ)
}、関数(エラー) {
//例外処理
console.log(err);
});

上記のコードは次のように変換できます:

コードをコピーします コードは次のとおりです:

試してみてください{
// 競技以外のアラーム情報を取得
var アラームデータ = アラームデータ例外比較();
render(alarmData);
// アラーム情報に基づいて競合情報を問い合わせます
var CompareData = getCompareInfo(alarmData);
render(compareData);
} キャッチ(エラー) {
console.log(err.message);
}

上記の例では、例外処理が最後に配置されているため、特定のリンクで例外が発生した場合、どのイベントが原因であるかを正確に知ることができません。

2.2 jQuery.Deferred の問題

非同期操作は jQuery にも実装されていますが、この実装は主に次の点で Promise/A 仕様に準拠していません。

a. パラメータの数: 標準 Promise は 1 つのパラメータのみを受け入れることができますが、jQuery は複数のパラメータを渡すことができます

コードをコピーします コードは次のとおりです:

関数 asyncInJQuery() {
var d = new $.Deferred();
setTimeout(function() {
d.resolve(1, 2);
}, 100);
d.promise()
を返します }
asyncInJQuery().then(function(val1, val2) {
console.log('出力: ', val1, val2);
});
// 出力: 1 2

b. 結果処理での例外の処理

コードをコピーします コードは次のとおりです:

関数 asyncInPromise() {
新しい Promise(function(resolve) を返す {
setTimeout(function() {
var jsonStr = '{"name": "mt}';
solve(jsonStr);
}, 100);
});
}
asyncInPromise().then(function(val) {
var d = JSON.parse(val);
console.log(d.name);
}).then(null, function(err) {
console.log('エラーを表示: ' err.message);
});
// エラーを表示: 入力の予期しない終了
関数 asyncInJQuery() {
var d = new $.Deferred();
setTimeout(function() {
var jsonStr = '{"name": "mt}';
d.resolve(jsonStr);
}, 100);
d.promise()
を返します }
asyncInJQuery().then(function(val) {
var d = JSON.parse(val);
console.log(d.name);
}).then(function(v) {
console.log('success: ', v.name);
}、関数(エラー){
console.log('エラーを表示: ' err.message);
});
//キャッチされない SyntaxError: 入力の予期しない終了

このことから、Promise はコールバック関数の結果処理を実行し、コールバック関数の実行中に例外をキャプチャできるが、jQuery.Deferred はできないことがわかります。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Python vs. JavaScript:開発環境とツールPython vs. JavaScript:開発環境とツールApr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

JavaScriptはCで書かれていますか?証拠を調べるJavaScriptはCで書かれていますか?証拠を調べるApr 25, 2025 am 12:15 AM

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptの役割:WebをインタラクティブでダイナミックにするJavaScriptの役割:WebをインタラクティブでダイナミックにするApr 24, 2025 am 12:12 AM

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Python vs. JavaScript:ユースケースとアプリケーションと比較されますPython vs. JavaScript:ユースケースとアプリケーションと比較されますApr 21, 2025 am 12:01 AM

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScript通訳者とコンパイラにおけるC/Cの役割JavaScript通訳者とコンパイラにおけるC/Cの役割Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター