2012-04-04 6 views
1

私はnode_redisでNode.jsを使用していますが、オブジェクトをループしてRedisでデータを検索してから結果を返しています。forループはredis delayからアイテムを取得します

私はそれがこのような設定があります。

 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の呼び出しを完了する前に、それがループしていることです。実際には合計値が更新される前にコールバックが呼び出されます。遅延のためにいくつかの項目をスキップするようだ。

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

ありがとうございました!私はこのようにそれを更新した

オクラホマので、::

EDITそれがうまくいくように

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++; 
       }); 
      }; 
     } 

これはと思われる、それは適切な時にコールバックをトリガし、しかし、それは最後のようですキーが更新されています。

+0

あなたは再帰バージョンを試してみましたか? –

+0

Hm、forループ内またはその代わりに? – dzm

答えて

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); 
}) 
+0

あなたの返信ありがとう!私も同様の問題を抱えていました。あなたのコードは、私の仕事を手助けするために必要な手がかりを私に与えました。 – andyengle