1

私はまだnode.jsにアクセスしようとしていますが、おそらく正しくないものがいくつかあります。私が達成しようとしているのは、最初に部屋のリストを含むhmapを照会することです。このリストは、各部屋の部屋名などの詳細を取得するために繰り返されます。

クエリが返すものは次のとおりです。

redis 127.0.0.1:6379> lrange rooms 0 -1
1) "room:5000"

redis 127.0.0.1:6379> hgetall room:5000
1) "name"
2) "room1"
3) "admin"
4) "user:1001"
5) "public"
6) "true"

これがroutes.index内の私の関数です

exports.index = function(req, res){

    var render_rooms = new Array();

    req.app.settings.redis.lrange('rooms',0,-1, function(error, rooms) {

        if (error) {
            console.log('Error: '+ error);
            }
        else {

            rooms.forEach(function(room){
                console.log("room: " + room);

                req.app.settings.redis.hgetall(room, function(error, roomdetails){
                    if (error) {
                        console.log('Error: '+ error);
                        }
                    else {
                        console.log("roomdetails: " + roomdetails.public);

                        if(roomdetails.public == "true"){
                            render_rooms.push(roomdetails.name);

                        }

                    }
                });

            });




        //  console.log('Name: ' + result);
      //    res.render('account', { title: 'account title', user: req.user.username, votes: result });
        }

    });


    console.log("length: " + render_rooms.length);
    res.render('index', { title: 'Index', username: req.user.username, rooms: render_rooms });

};

これを実現するためにnode_redisを適切に使用しているかどうかはわかりません。さらに、すべての部屋の詳細を配列に格納するというアイデアを思いつきました。これをビューに送信するのを楽しみにしています。どうやら、いくつかの重要なコールバック機能が欠落しているため、リストがいっぱいになる前に呼び出されると思うので、リストには常に要素が表示されません。しかし、私はそれをいじることができません。誰かがそれがどのように「機能する」べきかについてもう少し詳しく説明してもらえますか?

4

1 に答える 1

3

基本的な問題は、render_roomsすべての非同期処理が完了するまで配列のレンダリングを待つ必要があることです。現在の記述方法res.renderは、非同期Redisクエリが完了する前に呼び出されています。

このようなもの:

exports.index = function(req, res){

    var render_rooms = new Array();

    req.app.settings.redis.lrange('rooms',0,-1, function(error, rooms) {

        // Keep track of the number of rooms we have left to process.
        var roomcount = rooms.length;

        if (error) {
            console.log('Error: '+ error);
            }
        else {

            rooms.forEach(function(room){
                console.log("room: " + room);

                req.app.settings.redis.hgetall(room, function(error, roomdetails){
                    if (error) {
                        console.log('Error: '+ error);
                        }
                    else {
                        console.log("roomdetails: " + roomdetails.public);

                        if(roomdetails.public == "true"){
                            render_rooms.push(roomdetails.name);
                        }

                        // Render code moves to here and is only run after all rooms
                        // have been processed.
                        if (--roomcount === 0) {
                            console.log("length: " + render_rooms.length);
                            res.render('index', { 
                                title: 'Index', 
                                username: req.user.username, 
                                rooms: render_rooms 
                            });
                        }
                    }
                });
            });
        }
    });
};

これが何をしているのか理解できたら、このタイプのフローをよりクリーンにサポートするasync.forEachかを使用して、少しクリーンアップすることを検討してください。async.forEachSeries

于 2012-11-19T21:12:21.250 に答える