ホームページ ウェブフロントエンド jsチュートリアル NodeJ の同時および非同期コールバックの詳細な分析 process_node.js

NodeJ の同時および非同期コールバックの詳細な分析 process_node.js

May 16, 2016 pm 03:24 PM

同時と非同期というのは正確ではありません。連続的非同期と言うべきです。 NodeJs のシングルスレッド非同期機能により、複数の非同期操作が同時に実行されると、コールバックが最終的な実行結果を決定できなくなります。簡単な例を挙げてください:

for(var i = 0; i < 5; i++) {
  fs.readFile('file', 'utf-8', function(error, data){});
} 
ログイン後にコピー

ファイルを連続して読み取るために 5 つの非同期操作を開始しました。これは非常に簡単です。すべての非同期操作が完了したことを確認するにはどうすればよいでしょうか。後続の操作はすべて実行された後でのみ実行できるためです。ある程度経験のある学生であれば数え方を考えると思いますが、どうやって正確に数えるかはまた別の問題です。よく考えてください:

コールバックは、非同期操作が行われるたびにカウンターに 1 を加算し、非同期操作が終了するたびにカウンターを 0 にするかどうかを判断する関数です。このロジックは非常に単純で、実行時間とコールバック時間に関連するグローバル変数をカウンターとして必要とし、非同期メソッドに渡されたときに +1 演算を実行してからコールバック用の関数を返す必要がありますが、これは少し複雑です。ただし、「Js 関数の高度な使用法を参照してください:
」を参照してください。

var pending = (function() {
  var count = 0;
  return function() {
    count++;
    return function() {
      count--;
      if (count === 0) {
        // 全部执行完毕
      }
    }
  }
}); 
ログイン後にコピー

pending が呼び出されると、pending() になります。例:

var done = pending(); 
ログイン後にコピー

この時、カウント変数countは0に初期化され、返された関数はdone()がこの時に実行されるとどうなるでしょうか? pending によって返された最初の関数、つまり pending()() を直接実行することですか? まず、カウント変数 count+1 が返され、この関数が として直接渡されます。非同期メソッドへのコールバック。このコールバックを実行するときは、まずカウント変数 count-1 を設定し、次にカウントが 0 かどうかを判断します。0 の場合は、すべての非同期実行が完了したことを意味するため、連続した非同期操作が実現されます。同じコールバック。

鍵は 2 つのリターンにあります:

最初の戻り関数は count+1 で、その後コールバックが必要な関数を返します

2 番目の return 関数は、コールバックが必要な関数です。実行されるとカウントが 1 され、すべての非同期実行が完了したかどうかを判断します。完了すると、
がコールバックされます。

複数のファイルを読み取るための非同期コールバックの実際の例を見てください:

var fileName = ['1.html', '2.html', '3.html'];
var done = pending(function(fileData) {
  console.log('done');
  console.log(fielData);
});
for(var i = 0; i < fileName.lenght; i++) {
  fs.readFile(fileName[i], 'utf-8', done(fileName[i]));
}
ログイン後にコピー

完了したものは、コールバックして実行するメソッドをラップするために保留中のメソッドを使用します。次に、保留中のメソッドを改善する必要があります。

var pending = (function(callback) {
  var count = 0;
  var returns = {};
  console.log(count);
  return function(key) {
    count++;
    console.log(count);
    return function(error, data) {
      count--;
      console.log(count);
      returns[key] = data;
      if (count === 0) {
        callback(returns);
      }
    }
  }
}); 
ログイン後にコピー
callback はコールバック関数です。var done = pending(callback) の場合、done は実際には戻り値の添字として使用できるパラメーターを持っているため、ループ本体では Inned( fileName[i])、ファイル名が渡されます。このdone()はcount+1を実行した後、非同期メソッドに渡すコールバック関数を返します。前述したように、このコールバック関数はcount変数に基づいて実行するかどうかを決定します。 . にファイルの内容を渡します。つまり、戻ります。さて、実行してみましょう。結果が正確に表示されると思います。


0

1
2
3
2
1
0
完了
{"1.html": "xxx"、"2.html": "xxx"、"3.html": "xxx"}

0-3 から 0 までのカウントと、コールバック関数の出力完了とファイルの内容から明らかです。


この問題は解決されました。そのようなメソッドをカプセル化して再利用する方法を考える必要があります。そうしないと、毎回保留を書くのは非科学的ではないでしょうか。


テンプレート解析のサブテンプレート操作に適用される UnJ (NodeJs ベースの Web 開発フレームワークの 1 つ) の処理メソッドを見てみましょう。


unjs.asyncSeries = function(task, func, callback) {
  var taskLen = task.length;
  if (taskLen <= 0) {
    return;
  }
  var done = unjs.pending(callback);
  for(var i = 0; i < taskLen; i++) {
    func(task[i], done);
  }
} 
ログイン後にコピー

asyncSeries には 3 つのパラメータがあります。つまり、

タスク: 読み取る必要があるファイルなど、処理する必要があるオブジェクト。リストです。リストでない場合、またはリストの長さが 0 の場合、実行されません。


func: fs.readFile などの非同期メソッドがそれを通じて渡されます


callback: コールバックするメソッド


done は先ほどと同様に func に渡しますが、実行はしません。パラメータはアプリケーション側で制御できれば良いので、アプリケーション側に実行させます。


サブテンプレートを扱うときの操作を見てください:


var subTemplate = [];
var patt = /\{\% include \'(.+)\' \%\}/ig;
while(sub = patt.exec(data)) {
  var subs = sub;
  subTemplate.push([subs[0], subs[1]]);
}
unjs.asyncSeries(subTemplate, function(item, callback) {
  fs.readFile('./template/' + item[1], 'utf-8', callback(item[0]));
}, function(data) {
  for(var key in data) {
    html = html.replace(key, data[key]);
  }
}); 
ログイン後にコピー

サブテンプレートのリストは、サブテンプレートの分析に基づいて生成されたデータであり、各サブ項目の最初の値はサブテンプレートの呼び出しテキスト、つまり {% です。 include 'header.html ' %} のような文字列の場合、2 番目のパラメータはサブテンプレート ファイル名、つまり header.html
です。

asyncSeries の 2 番目のパラメーターは callback ですが、これは実際には 3 番目のパラメーターであり、前述したように、asyncSeries 内では実行されていません。ここでは、つまり callback(item[0]) とパラメータを指定します。これは、後で親テンプレート内のサブテンプレートを呼び出す文字列が、このパラメータに基づいて対応するサブテンプレートのコンテンツに置き換えられるためです。

このように、継続的な非同期が必要な限り、asyncSeries メソッドを使用して処理できます。非同期関係のため、プログラムの流れが少し複雑で、慣れていても突然理解できない場合があります。 、2 番目のパラメータのコールバックは、実際には 3 番目のパラメータによって生成されます。このコールバックとは一体何なのか疑問に思われるかもしれません。また保留中の返品が 2 件ありますが、これは理解しにくいため、さらに検討する必要があります。

これで、Js 関数の高度な機能を使用して、継続的な非同期コールバックが完了しました。ただし、NodeJ の非同期の性質により、値の転送を必要とする継続的な非同期操作など、プログラムの制御が非常に問題になります。これらはすべて、このアイデアと変更によって実現できます。

上記の内容は、エディターが共有した NodeJ の同時および非同期コールバック処理に関する知識です。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? フロントエンドのサーマルペーパーレシートのために文字化けしたコード印刷に遭遇した場合はどうすればよいですか? Apr 04, 2025 pm 02:42 PM

フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

誰がより多くのPythonまたはJavaScriptを支払われますか? 誰がより多くのPythonまたはJavaScriptを支払われますか? Apr 04, 2025 am 12:09 AM

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

javascriptの分解:それが何をするのか、なぜそれが重要なのか javascriptの分解:それが何をするのか、なぜそれが重要なのか Apr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? JavaScriptを使用して、同じIDを持つArray要素を1つのオブジェクトにマージする方法は? Apr 04, 2025 pm 05:09 PM

同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

Shiseidoの公式Webサイトのように、視差スクロールと要素のアニメーション効果を実現する方法は?
または:
Shiseidoの公式Webサイトのようにスクロールするページを伴うアニメーション効果をどのように実現できますか? Shiseidoの公式Webサイトのように、視差スクロールと要素のアニメーション効果を実現する方法は? または: Shiseidoの公式Webサイトのようにスクロールするページを伴うアニメーション効果をどのように実現できますか? Apr 04, 2025 pm 05:36 PM

この記事の視差スクロールと要素のアニメーション効果の実現に関する議論では、Shiseidoの公式ウェブサイト(https://www.shisido.co.co.jp/sb/wonderland/)と同様の達成方法について説明します。

Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Console.log出力の違い結果:なぜ2つの呼び出しが異なるのですか? Apr 04, 2025 pm 05:12 PM

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...

JavaScriptは学ぶのが難しいですか? JavaScriptは学ぶのが難しいですか? Apr 03, 2025 am 12:20 AM

JavaScriptを学ぶことは難しくありませんが、挑戦的です。 1)変数、データ型、関数などの基本概念を理解します。2)非同期プログラミングをマスターし、イベントループを通じて実装します。 3)DOM操作を使用し、非同期リクエストを処理することを約束します。 4)一般的な間違いを避け、デバッグテクニックを使用します。 5)パフォーマンスを最適化し、ベストプラクティスに従ってください。

PowerPointはJavaScriptを実行できますか? PowerPointはJavaScriptを実行できますか? Apr 01, 2025 pm 05:17 PM

JavaScriptはPowerPointで実行でき、外部JavaScriptファイルを呼び出したり、VBAを介してHTMLファイルを埋め込んだりすることで実装できます。 1. VBAを使用してJavaScriptファイルを呼び出すには、マクロを有効にし、VBAプログラミングの知識を持つ必要があります。 2。JavaScriptを含むHTMLファイルを埋め込みます。これは、シンプルで使いやすいが、セキュリティ制限の対象となります。利点には、拡張機能と柔軟性が含まれますが、欠点にはセキュリティ、互換性、複雑さが含まれます。実際には、セキュリティ、互換性、パフォーマンス、ユーザーエクスペリエンスに注意を払う必要があります。

See all articles