0

バックグラウンド キューの長さ、サービス依存関係への応答時間など、アプリケーションの状態に関する一連のメトリックを出力するモジュールを作成したいと考えています。これはDeferredを使用した Node JSです。

var metrics = {
    queueLength: function(def) {
        // .. Do some stuff to resolve the queue length ..
        def.resolve(45); // Example
    }
    // ... more metrics
}
for (i in metrics) {
    def = deferred();
    metrics[i](def);
    promiselist.push(def.promise);
    def.promise(function(result) {
        metrics[i] = result;
    }
}
return deferred(promiselist)(function(result) {
    console.log('All metrics loaded', result, metrics);
});

これにより、出力が生成されます

Metrics loaded [ [Function] ]  { queueLength: [Function] }

私が期待していたとき:

Metrics loaded [ 45 ]  { queueLength: 45 }

私は2つのことを間違っていると思いますが、それらを「適切に」修正する方法がわかりません:

  • そのreturn deferred([array of promises])(group promise)考えは通用しないようだ
  • 各反復で再利用されていることに気付いたdefので、複数のメトリックがある場合、おそらく最後のメトリックのみを追跡します。
4

2 に答える 2

1

Bergiが指摘したことのほとんどに同意します。メソッドを破棄するべきではなくmetrics、それらの内部で promise を作成して返す必要があります。

あなたができる他のいくつかの改善があります:

リストと配列専用のdeferred.map( に対応するものとして名前が付けられた[].map) があり、それを直接使用して promise の配列を解決できます。

deferred.map(promiselist).then(/* ... */)

さらに、完全に使用してループdeferred.mapを置き換えると、構成を改善できます。for..in

var result = {}; 
deferred.map(Object.keys(metrics), function (name) {
  return metrics[name]().aside(function (value) { result[name] = value; }); 
}).done(function (resultArr) {
  console.log('All metrics loaded', resultArr, result);
});
于 2013-10-13T10:51:11.897 に答える
0
metrics[i] = result;

それは悪い考えです。metricsオブジェクトを破棄するべきではありません。そのプロパティは、関数であり、関数のままであると想定されています。結果を含むオブジェクトが必要な場合は、新しいオブジェクトを作成します。

return deferred([array of promises])(group promise) のアイデアは機能していないようです

ドキュメントとコードから、ライブラリが引数として配列をサポートしていないことがわかります。以下を使用する必要がありますapply

deferred.apply(null, promiselist)

def が反復ごとに再利用されていることに気付いたので、複数のメトリックがある場合、おそらく最後のメトリックのみを追跡します。

いいえ、再利用されていません。ループターンごとに新しい遅延オブジェクトを作成しています。ただし、変数をローカルにするvarキーワードを忘れました。

変数にも問題があります。i変数は各 promise コールバックのクロージャー スコープ内にありません。つまり、コールバックが解決されると、変数には最後のループ ターンからの値が既に含まれていることになります。ループ内の JavaScript クロージャを確認してください – 簡単な実用例.

小さな設計上の欠陥は、metricsメソッドが解決する引数として deferred を取ることです。引数を取らず、自分で作成 (および管理) した結果に対して promise を返した方がよいでしょう。

var metrics = {
    queueLength: function() {
        var def = deferred();
            // .. Do some stuff to resolve the queue length ..
            def.resolve(45); // Example
        return def.promise;
    }
    // ... more metrics
};

var results = {},
    promiselist = [];
for (var p in metrics) {
    promiselist.push( metrics[p]().aside( function(_p) {
        return function(result) {
            results[_p] = result;
        };
    }(p) ) );
}
return deferred.apply(null, promiselist).then(function(resultArr) {
    console.log('All metrics loaded', resultArr, results);
    return results;
});
于 2013-10-12T13:27:16.930 に答える