2011-07-10 13 views
0

私はnode.jsがイベント駆動型であることを知っていますが、私はこの非同期を行うべきですが、私はそれを行う方法を見つけることができません。Node.jsの同期mysql

ので、私はそれが同期します。この

var querystr = "SELECT * FROM groups"; 
    var result = ""; 
    dbClient.query(querystr, function (err, res, fields) { 
     if (err) { 
      console.log(err); 
      return; 
     } 
     for(var i in res) { 
      result = result + "@" +res[i].name + " ="; 
      for (var j in res[i].members.split(",")) { 
       var memberquery; 
       if (j.substr(0,1) == "@") { 
        memberquery = "SELECT name FROM groups WHERE id = "+j.substr(1, j.length-1); 
       } else { 
        memberquery = "SELECT username FROM users WHERE id= "+j; 
       } 
       dbClient.query(memberquery, function(err, memres, fields) { 
        var membername = ""; 
        if (typeof memres[0].username == "undefined") { 
         membername = "@"+memres[0].name; 
        } else { 
         membername = memres[0].username; 
        } 
        result = result + " " + membername; 
       }); 

      } 
      result = result + "\n"; 
     } 
    }); 

問題は内部用で持っています。 は基本的に私はグループをチェックし、期待される出力は、私は通常、この種の問題については、以下のいずれかのようパターンを使用

Group1 = member, member 
Group2 = member, member 
+0

クイックアサイドのカップル:最初のクエリ結果の最初のパスを実行し、2回目のパスでメンバーにループすると、SELECT名前FROMグループクエリが回避できます。さらに、DBが正常に正規化されていれば、すべてのテーブル照合作業を単一の照会で行うことができます。 – Metal

答えて

3

あるので、メンバーに伝え、結果変数にドキュメントを生成しています。一言で言えば、リストを取得し、リストを処理する関数を呼び出します。その関数は、リストが完了するまで自身を呼び出します。アキュムレータに入ると結果が集まります。リストが空の場合は、コールバックを通じて蓄積したものを返します。 @Andrey Sidorovが彼の返答で実証したことを達成するもう一つの方法です。

//cb is (err, res) 
function getData(cb){ 
    var querystr = "SELECT * FROM groups"; 
    var result = ""; 

    dbClient.query(querystr, function (err, res, fields) { 
     if (err) 
      cb(err); 
     else { 
     var groups = []; 
     for (var ndx in res) 
      groups = groups.concat(res[ndx].members.split(",")); 

     getMembers(groups, [], cb); 
     } 
    }); 
} 

function getMembers(members, sofar, cb){ 
    var member = members.shift(); 

    if (!member) 
    cb(null, sofar); 
    else { 
    var memberquery; 
    var params; 

    if (member.substr(0,1) == "@") { 
     memberquery = "SELECT name FROM groups WHERE id = ?"; 
     params = [member.substr(1, member.length-1)]; 
    } else { 
     memberquery = "SELECT username FROM users WHERE id = ?"; 
     params = [member]; 
    } 

    dbClient.query(memberquery, params, function(err, res) { 
     if (err) 
     cb(err); 
     else { 
     var membername = ""; 
     if (typeof res[0].username == "undefined") { 
      membername = "@" + res[0].name; 
     } else { 
      membername = res[0].username; 
     } 

     sofar.push(membername); 

     getMembers(members, sofar, cb); 
     } 
    }); 
    } 
} 
+0

あなたの例では、クエリを順番に呼び出していることに注意してください。 –

+0

@Andrey true。ただし、node-mysqlはそれらをキューに入れておき、前の処理が完了したときにのみ問題を発行します。しかし、あなたは正しいです。プールを使用してmysqlに同時にクエリを発行できれば、いくつかの並列化ができます。 –

+0

@Andreyと@Geoffに感謝します。私はasync.jsのおかげで解決策を見つけたので、私はその質問を削除したと思いました。私はGeoffのようなアプローチを使用しています(実際にはgetMembersという関数があります)。しかし、私は出力への応答を期待していないので、もう1つ見てみましょう。これは完全に非同期です。 –

1
function do_queries(resultCallback) 
{ 
    var querystr = "SELECT * FROM groups"; 
    var result = ""; 
    var num_queries_left = 0; 
    dbClient.query(querystr, function (err, res, fields) { 
     if (err) { 
      console.log(err); 
      return; 
     } 

     // calculate number of invocations of second sub-query 
     for(var i in res) 
      num_queries_left += res[i].members.split(",").length; 

     for(var i in res) { 
      result = result + "@" +res[i].name + " =";     
      for (var j in res[i].members.split(",")) { 
       var memberquery; 
       if (j.substr(0,1) == "@") { 
        memberquery = "SELECT name FROM groups WHERE id = "+j.substr(1, j.length-1); 
       } else { 
        memberquery = "SELECT username FROM users WHERE id= "+j; 
       } 
       dbClient.query(memberquery, function(err, memres, fields) { 
        var membername = ""; 
        if (typeof memres[0].username == "undefined") { 
         membername = "@"+memres[0].name; 
        } else { 
         membername = memres[0].username; 
        } 
        result = result + " " + membername; 
        num_queries_left--; 
        if (num_queries_left == 0) 
        { 
         resultCallback(result); 
         return; 
        } 
       }); 

      } 
      result = result + "\n"; 
     } 
    }); 
} 


do_queries(function(result) { 
    console.log(result); 
}); 
関連する問題