2016-12-13 1 views
-1

2つの関数AとBの両方がconnection.query(...)メソッドを介してmysql DBを呼び出しているとします。私はwhileループを使用して、関数Aの応答を反復処理しています。NodeJS:関数内の関数です。どのように同期させるには?

また、関数Aからの応答で、関数Bで別のDB要求を呼び出し、その中で別のwhileループの結果を反復処理します。

非同期の問題の取得。これを解決する方法。

function A(){ 
    while(){ //Say, Repeat 10 times 
    function B(){ 
     while(){ 
      some_result; 
     } 
    } 
    }   
} 

これは、実際のコードです:Nodejsで

app.get('/getmenu', function (req, res) { 

    connection.query('SELECT * from zaitoon_menutypes', function (err, rows) { 
    var output = []; 
    var i=0; 
    var j; 
    var main= rows[0].mainType; 
    var submenu=[]; 
    var items=[]; 

    //Iterate through complete menu types 
    while(i < rows.length){ 

     //Do NOT MENU TYPE switch case 
     if (main == rows[i].mainType){ 


     connection.query("SELECT * from zaitoon_menu WHERE type='type'" , function (err2, rows2, fields2){ 
     console.log('*************************'+rows2.length); 
     items = []; 
     j=0; 
     while(j < rows2.length){ 
      items.push(
      { 
      "itemCode":rows2[j].code, 
      "itemName":rows2[j].name, 
      "itemPrice":rows2[j].price 
      } 
     ); 
      j++; 
     } 
     console.log(items); 

     }); //End Connection 

     //Create Sub-menu 
     submenu.push(
      { 
      "subType" : rows[i].subType, 
      "subName" : rows[i].subName, 
      "items" : items 
      } 
     ); 

     if (i ==(rows.length-1)){ 
     output.push(
     { 
      "mainType":rows[i-1].mainType, 
      "mainName":rows[i-1].mainName, 
      "submenu": submenu 
     } 
     ); 
     } 
     } 

     //SWITCH NEXT TYPE 
     else { 
     main = rows[i].mainType; 
     output.push(
     { 
      "mainType":rows[i-1].mainType, 
      "mainName":rows[i-1].mainName, 
      "submenu": submenu 
     } 
     ); 
     var submenu=[]; 

     } 

     i++; 
    } 

    if (!err){ 
     res.setHeader('Content-Type', 'application/json'); 
     res.header("Access-Control-Allow-Origin", "*"); 
     res.status(200).send(JSON.stringify(output)) 
    } 
    else 
     res.status(500).send('Error ')  
    }) 
}) 

答えて

0

まれあなたは同期呼び出しを行うべきです。あなたがそれを間違って実行すると、あなたのシステムをホースすることになります。特にトラフィックが多い場合は特にそうです。 Nodejsはシングルスレッドであり、正常に動作するためには非同期で構築されています。

あなたの場合、基本的にはいくつかのデータベースレコードを照会し、それらを使用していくつかのJSONオブジェクトを設定しています。あなたがすべて完了したら、jsonオブジェクトの配列であるレスポンスを送信したいのです...そうですか?

約束を使用することを強くお勧めします。これを扱うことができる非常に普及しているライブラリはBluebirdです:http://bluebirdjs.com/docs/getting-started.html

実際に理解できるように約束をお読みください。短い答えは、すべての非同期を保持し、同時に非同期コードを同期しているかのように非同期コードを「読み取り」にすることができるようにすることです。

最終的にここで行う必要があるのは、データベースクエリを約束し、データをオブジェクトにプッシュして解決することです。 Promise.all()を使用するなど、すべてのデータベース呼び出しが解決されたら、オブジェクトとともにres.sendを返す必要があります。非同期の問題を回避しながら必要なものをすべて水和する必要があります。

あなたが行う可能性のある例を示します。 これはテストされていないことに注意してください。私は単にメモ帳でこれをやっています。++ ...コピー/貼り付けすれば確実にうまくいかないでしょう!しかし、それはうまくいけば正しい道に沿ってあなたを指摘する必要があります....

var Promise = require('bluebird'); 
var connection = require('mysqllibrary'); 

app.get('/getmenu', function (req, res) { 

    Promise.promisifyAll(connection); 

    connection.queryAsync('SELECT * from zaitoon_menutypes') 
    .then(function(rows){ 
     var output = []; 
     var i=0; 
     var j; 
     var main= rows[0].mainType; 
     var submenu=[]; 
     var items=[]; 
     var promises=[]; 


     //Iterate through complete menu types 
     while(i < rows.length){ 

      //Do NOT MENU TYPE switch case 
      if (main == rows[i].mainType){ 

      promises.push(connection.queryAsync("SELECT * from zaitoon_menu WHERE type='type'") 
          .then(function(rows2){ 
           console.log('*************************'+rows2.length); 
           items = []; 
           j=0; 
           while(j < rows2.length){ 
            items.push(
            { 
            "itemCode":rows2[j].code, 
            "itemName":rows2[j].name, 
            "itemPrice":rows2[j].price 
            } 
           ); 
            j++; 
           } 
           console.log(items); 
          })); 

      //Create Sub-menu 
      submenu.push(
       { 
       "subType" : rows[i].subType, 
       "subName" : rows[i].subName, 
       "items" : items 
       } 
      ); 

      if (i ==(rows.length-1)){ 
       output.push(
       { 
        "mainType":rows[i-1].mainType, 
        "mainName":rows[i-1].mainName, 
        "submenu": submenu 
       }); 
      } 
      } 
      //SWITCH NEXT TYPE 
      else { 
      main = rows[i].mainType; 
      output.push(
      { 
       "mainType":rows[i-1].mainType, 
       "mainName":rows[i-1].mainName, 
       "submenu": submenu 
      } 
      ); 
      var submenu=[]; 
      } 
      i++; 
     } 

     return Promise.all(promises).then(function() { 
      console.log("Output object has been hydrated"); 
      return output; 
     }); 

    }).then(function(output){ 
     res.setHeader('Content-Type', 'application/json'); 
     res.header("Access-Control-Allow-Origin", "*"); 
     res.status(200).send(JSON.stringify(output)) 
    }).catch(function(err){ 
     res.status(500).send('Error: ' + err)  
    }); 

}); 
関連する問題