【问题标题】:NodeJS: Function inside function. How to make it synchronous?NodeJS:函数内部的函数。如何使其同步?
【发布时间】:2017-04-28 23:13:31
【问题描述】:

假设有两个函数 A 和 B 都通过 connection.query(...) 方法调用 mysql DB。我正在使用 while 循环来遍历函数 A 中的响应。

再次,根据函数 A 的响应,在函数 B 中调用另一个 DB 请求并遍历它的结果,在内部的另一个 while 循环中。

遇到异步问题。如何解决这个问题。

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

这是实际代码:

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 ')     
  })
})

【问题讨论】:

    标签: javascript node.js express async-await


    【解决方案1】:

    在 Nodejs 中,很少您应该进行同步调用。如果你做错了,它一定会影响你的系统……尤其是当你有很多流量的时候。 Nodejs 是单线程的,并且完全围绕异步构建,以便正常工作。

    在您的情况下,您实际上是在查询一些数据库记录并使用这些记录来填充一些 JSON 对象。当你都完成后,你想发送一个响应,它是一个 json 对象数组......对吗?

    我强烈建议您考虑使用 Promises。一个非常流行的可以处理这个问题的库是 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)     
      });   
    
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 2018-01-09
      • 2016-03-30
      • 1970-01-01
      • 2013-11-20
      相关资源
      最近更新 更多