2

node.js の非同期性に混乱しました。その中に小さなプロジェクトを書いていますが、以前の (同期) プログラミングの経験が邪魔になります。

非同期コードを記述するかどうか/どこに記述するかをどのように決定すればよいですか?

たとえば、フィールドを持つモデルがあり、それぞれにいくつかの検証ルールがあります。

model = { title: text_validation, 
  subtitle: text_validation }

text_validation = { max_len: 10,
  required: true,
  url: true }

モデルを検証するときは、すべてのフィールドを反復処理して、ルールが合格するかどうかを確認します。これらは非常に迅速な機能です。

Model.validate = function() {
  validator = {};
  fields = Object.keys(Model);
  fields.forEach(function(field) {
    validator[field_name] = field.validate();
  });
}

Field.validate = function() {
  validator = [];
  rules.forEach(function(rule) {
    if (rule is not valid)
      validator.push(rule)
  });

  return validator;
}

このような短くて速い反復でコールバックを使用する必要がありますか?

ここの限界はどこですか?node.js は常に非同期である必要がありますか、それとも十分に速い場合は同期ループまたは w/e を許可できますか? 可能であれば、いつ、どこで同期/非同期を使用するかの例を参照してください。

4

2 に答える 2

6

あなたはおそらくすべきではありません。ほとんどの場合、非同期ロジックが必要になるのは、アプリケーションの外部から何か(主にファイル、データベース、およびネットワークの操作)を待っている場合のみです。アプリケーション内のコードを非同期的に遅延させると、コードをある時点で実行する必要があるため、パフォーマンス上の利点はありません。

于 2012-06-27T12:28:34.213 に答える
2

すでにコメントで述べましたが、例も挙げておくとよいと思います。

コールバック操作と非同期操作の概念は異なりますが、関連しています。使用 forEachしているループはまったく非同期ではありません。多かれ少なかれforEachルックスの定義は次のとおりです。

Array.prototype.forEach = function(callback) {
    var l = this.length;
    for (var i = 0; i < l; i++)
        callback(this[i], i);
};

ご覧のとおり、これには非同期のものは何もありません。はcallback、ループ ステップごとに同期的に実行されます。

では、ループを非同期にする方法は? さて、あなたはこれを試すことができます:

Array.prototype.asyncForEach = function(applier, finished) {
    var self = this;
    var l = self.length;
    var call = function(i) {
        process.nextTick(function() {
            applier(self[i], i);
            if (i == l-1)
                finished();
            else
                call(i+1);
        });
    }
    call(0);
};

そして、次のように使用できます。

var x = [1,2,3,4,5,6,7,8,9,10];
x.asyncForEach(function(el, index) {
    /* apply function to each el and index */
    console.log(el);
}, function() {
    /* This will be called when the loop finishes! */
    console.log('Finished!');
});
/* Let us check whether the loop is really asynchronous.
   The following code should fire BEFORE loop! */
console.log('Is it asynchronous?');

ご覧のとおり、 のように簡単でシンプルではありませんforEach。ただし、これにより、ループの反復間で他のコードを実行できます (process.nextTickメソッドの魔法)。そのため、高可用性が得られますが、ループが完了するまでにさらに時間がかかるという代償があります。反復間で配列を変更することは可能であり、アプリがクラッシュする可能性があることに注意してください。:D

コメントで言ったように、実際に非同期ループに切り替える必要があるほど長い間ループが機能しているのを見たことがありません。そして、私はいくつかの市場データを処理してきました (ただし、JavaScript ではなく Python を使用しました - これが理由かもしれません)。そして、lanzz がコメントしたように、ループに時間がかかりすぎる場合は、フォークすることをお勧めします。または、効率的な言語 (C?) で記述された WebService (またはNode.JS addon ) を作成します。

于 2012-06-28T06:46:31.083 に答える