0

結果はおかしくないかもしれませんが、私は 1 ~ 2 か月前に Node を使い始めたので、私にとっては...

(Redis コマンド)によって返された配列の他のすべてのhgetall値を並べ替えるループがあり、そのループで関数を呼び出して、並べ替えられた配列にキーが格納されている別のテーブルからすべての値を取得します。これは思ったより説明が難しかったです。これが私のコードです:

Pastebin: http://pastebin.com/tAVhSUV1 (または以下を参照)

function getInfo (cn, callback) {
        var anArray = [];
        redis_client.hgetall('chat_info:' + cn, function (err, vals) {
                if(err) { throw err; }
                for(i in vals) {
                        anArray.push(vals[i]);
                }
                return callback(anArray);
        });
}

redis_client.hgetall('chat_rooms:' + POST.chat_name, function (err, val) {
        if(err) { throw err; }
        var     vars = [],
                rArr = [];

        for (i in val) {
                vars.push(i);
        }
        for(var i = 0; i < vars.length; i += 1) {
                if(i%2 === 0) {
                        getInfo(vars[i], function (hej) {
                                rArr.push(hej);
                        });
                }
        }      
});

への呼び出しからのコールバックは、getInfo()ループ全体の後に実行されます。ここで何かを見逃していますか?それができないからですよね?(rArr(ループの直後)を使用すると空になりますが、コールバックでログに記録すると、ループのに他のすべてが書き込まれた後にログに記録されます)

4

1 に答える 1

0

はい、それはおそらく正常です。

コールバックは呼び出し後に実行されることを理解してhgetallください。つまり、redis 関数が何かを受け取ると、コールバックが呼び出されます。つまり、すべてのコールバックを後で実行できます。

JavaScript は 1 つのスレッドでのみ機能するため、呼び出しhgetallは for ループに入ると実行をブロックする必要があります。しかし、より確実に async IO を使用しているためです。for ループが終了すると、javascript イベント ループ内でキューに入れられた各コールバックの呼び出しが開始されます。

編集

残念ながら、目的を達成するには、コードを他の多くのコールバック内にラップする必要があります。このプロジェクトを使用して簡単にすることができます: https://github.com/caolan/async

を使用してインストールできるはずですnpm install async

あなたはそのようなことをしなければならないでしょう:

function getInfo (cn) {
        return function(callback) {
            var anArray = [];
            redis_client.hgetall('chat_info:' + cn, function (err, vals) {
                if(err) { throw err; }
                for(i in vals) {
                        anArray.push(vals[i]);
                }
                return callback(anArray);
            });
        };
}

redis_client.hgetall('chat_rooms:' + POST.chat_name, function (err, val) {
        if(err) { throw err; }
        var     vars = [],
                rArr = [],
                callbacks = [];

        for (i in val) {
                vars.push(i);
        }

        for(var i = 0; i < vars.length; i += 1) {
                if(i%2 === 0) {
                        callbacks.push(getInfo(vars[i]));
                }
        }

        async.series(callbacks, function (err, results) {
           // Final code here
        });
});
于 2013-12-14T16:06:15.023 に答える