1

node.jsとnode_redisを使用していて、オブジェクトをループしてRedisでデータを検索し、結果を返しています。

私はそれを次のように設定しています:

        for (var key in items) {
            if (items.hasOwnProperty(key)) {

                    app.client.llen(items[key].id+'_click', function(err, total) {
                        items[key].total = total;

                    });
            }
        }

       callback(items);

問題は、redisの呼び出しを完了する前にループすることです。したがって、実際に合計値が更新される前に、コールバックが呼び出されます。また、遅延により一部の項目をスキップしているようです。

これを処理するためのより良い方法はありますか?

ありがとうございました!

編集:

わかりました、それで私はそれをこのように更新しました:

   getTotal(function () {
       callback(items);
   });

   getTotal = function (callback) {

       var count = 1;

       for (var key in items) {
           if (items.hasOwnProperty(key)) {
               app.client.llen(items[key].id + '_click', function (err, total) {
                   items[key].total = total;

                   if (items.length == count) {
                       callback();
                   }

                   count++;
               });
           };
       }

これは機能するようで、適切なタイミングでコールバックをトリガーしますが、最後のキーのみが完全に更新されているようです。

4

1 に答える 1

2

最初の例は、Redis クライアント呼び出しが非同期であるのにループが同期であるため、機能しません。2 番目の例は、Javascript のクロージャー管理のため、うまく機能しません。クロージャーが正しく処理され、それに応じてすべての合計フィールドが更新されるように、ループ自体に適切なスコープが必要です。

ここでは forEach を使用する方が簡単なようです。

getTotal = function (callback) {
  var count = 0;
  Object.keys( items ).forEach( function(key) {
    ++count;
    app.client.llen(items[key].id + '_click', function (err, total) {
      items[key].total = total;
      if ( --count == 0 ) {
        callback( items );
      }
    })
  })
}

getTotal( function(items) {
  console.log( items );
})
于 2012-04-05T09:08:25.687 に答える