2016-09-28 8 views
-1

背景情報ノードJS/Expressアプリケーション -

関数内で関数を呼び出す私は、値のリストを照会するのRedisデータベースに接続するノード/ Expressアプリケーションを持っています。そして、戻り値の各値について、さらにクエリを実行する必要があります。

問題

最初のクエリ(Redisのコマンド「スキャン」)が正常に動作しますが、予想通り、私は最初の結果セット内の各項目の試みHGETALLクエリが動作していません。

この問題を示すために、34行目にconsole.logコマンドを追加して、現在のスキャンレコードの値を出力してから、HGETALL(36行目)のコールバック関数で再度出力しました。値は異なります。私の考えでは、それらは同じでなければなりません...しかし、node.jsが動作する方法については基本的なものだと思います。コードから

コード

27 router.get('/', function(req, res, next) { 
28   redis.send_command("SCAN", [0,"MATCH", "emergency:*"], function(err, reply) { 
29     if (reply) { 
30       var retdata = []; 
31       console.log('length is: ' + reply[1].length); 
32       for (var i = 0; i < reply[1].length; i++) { 
33         var emergIP = reply[1][i]; 
34         console.log('emergIP outside the call: ' + emergIP); 
35         redis.hgetall(emergIP, function (err, data) { 
36           console.log('emergIP inside the call: ' + emergIP); 
37           if (data) {    
38             var temp = emergIP.split(":"); 
39             var key = temp[1]; 
40             console.log('the key is: ' + key); 
41             //retdata.push({key:data.callerid}); 
42           } 
43         }); 
44       }//end for loop 
45       res.send(JSON.stringify(retdata)); 
46     } //end if 
47     else { 
48       //no emergency data defined yet 
49       var retval = {"res":false, "msg":"no emergency data defined"}; 
50       res.send(JSON.stringify(retval)); 
51     
52     }    
53   }); //end send_command 
54 }); 
55 

出力

length is: 8 
emergIP outside the call: emergency:10.1 
emergIP outside the call: emergency:10.2 
emergIP outside the call: emergency:10.13 
emergIP outside the call: emergency:10.14 
emergIP outside the call: emergency:10.18.90 
emergIP outside the call: emergency:10.19 
emergIP outside the call: emergency:10.20 
emergIP outside the call: emergency:10.244 
GET /emergency/ 200 220.368 ms - 2 
emergIP inside the call: emergency:10.244 
the key is: 10.244 
emergIP inside the call: emergency:10.244 
the key is: 10.244 
emergIP inside the call: emergency:10.244 
the key is: 10.244 
emergIP inside the call: emergency:10.244 
the key is: 10.244 
emergIP inside the call: emergency:10.244 
the key is: 10.244 
emergIP inside the call: emergency:10.244 
the key is: 10.244 
emergIP inside the call: emergency:10.244 
the key is: 10.244 
emergIP inside the call: emergency:10.244 
the key is: 10.244 

質問

私はこの問題は、私がsend_command機能のコールバックを期待していていることだと思います逐次的に起こる。言い換えれば、別の関数呼び出しの中で関数呼び出しを行うことになっていないことが問題なのかもしれません。 これは私の最初のノードアプリケーションです...私は行くにつれて学びます。

何か提案がありがとうございます。あなたが閉鎖とすぐに、呼び出される関数を利用することができます代わりにasync.forEachを使用しての

+0

あなたの投稿はhttp://stackoverflow.com/questions/9644197/sequences-execution-in-node-jsの複製です – amitmah

+0

@amitmah、はい、あなたは正しいと思います。しかし私は、その記事を見つけるために検索するための適切な用語を知らなかったと思います。私は自分の質問に自分の質問にフレーズを付けるかもしれない他人のために私の質問を残すべきかどうか疑問に思います...? – Happydevdays

答えて

0

// get all elements from redis 
function getAll(emergIP, callback) { 
    redis.hgetall(emergIP, function (err, data) { 
    if (err) { 
     return callback(err); 
    } 

    console.log('emergIP inside the call: ' + emergIP); 
    if (data) { 
     var temp = emergIP.split(":"); 
     var key = temp[1]; 
     console.log('the key is: ' + key); 
    } 

    return callback(null, data); 
    }); 
} 

// Iterate all over the results 
function getResults (reply, callback) { 
    var retdata = []; 
    console.log('length is: ' + reply.length); 
    var length = reply.length; 

    if (!length) { 
    return callback(null, retdata); 
    } 

    for (var i = 0; i < length; i++) { 
    var emergIP = [i]; 
    console.log('emergIP outside the call: ' + emergIP); 

    (function (emergIP, i) { 
     getAll(emergIP, function (err, data) { 
     if (err) { 
      // @todo: how would you like to handle the error? 
     } 

     retdata.push({key:data.callerid}); 

     if (i === length - 1) { 
      return callback(null, retdata); 
     } 
     }); 
    }(emergIP, i)); 
    } //end for loop 
} 

router.get('/', function (req, res, next) { 
    redis.send_command("SCAN", [0, "MATCH", "emergency:*"], function (err, reply) { 
    if (reply) { 
     getResults(reply[1], function (err, data) { 
     if (err) { 
      // @todo: how would you like to handle this in case of error? 
     } 

     res.send(JSON.stringify(data)); 
     }); 
    } //end if 
    else { 
     //no emergency data defined yet 
     var retval = { "res": false, "msg": "no emergency data defined" }; 
     res.send(JSON.stringify(retval)); 

    } 
    }); //end send_command 
}); 

EDIT

私はコードを返すようにビットを変更しましたjsonを実行します。この場合、反復する結果がない場合、クライアントにはまったく応答が返されないため、完全なコードではありません。 async.eachの使用を検討してください:http://caolan.github.io/async/docs.html#.each

EDIT2

私は、コードを分離し、機能に分割しようとしました。これらの機能を別のファイルに移動し、それらをルーターに要求することができます。申し訳ありませんが、コードが正しく実行されることを許可しないタイプミスがある場合、私は実際にそれを実行しようとしませんでした。

+0

これは完全に機能します。私は、ノードクロージャとすぐに呼び出される関数を将来の参照のために調査します。ありがとうございました – Happydevdays

+0

唯一の他の関連する質問は、どのように/私はWebページに表示するための応答オブジェクトを介してこのデータを返す必要がありますか?私はretdata.push()メソッドのコメントを外してみましたが、動作していません – Happydevdays

+0

もちろん、それはあなたが非同期コードを実行していることを覚えているので動作しません:)あなたのコードはクライアントに応答を返します ' res.send(JSON.stringify(retdata)); 'redis.hgetallが終了するのを待たずに。もう少し答えとして解決策を投稿します。 –

関連する問題