Node.js处理异步

时间:2016-01-22 16:19:13

标签: javascript mysql json node.js asynchronous

我试图了解node.js的异步性质。 我有一条快速路线,我知道不会提供我需要的数据。基本上第一个mysql查询按预期工作100%,并且在res.json中返回的json数据是正确的。但是在第一个mysql函数中,我调用另一个函数'getOrderLines()',它总是返回'{“Item”:[]}'而不是我期望的数据。

我理解这种情况正在发生,因为节点的异步性质,但我似乎无法解决问题,我已经研究了承诺并写了一些基本的承诺,但无法让它在下面工作。

任何帮助都将不胜感激。

router.route('/salesOrders')
    .get(function (req, res) {
            mysql.query("QUERY", function (err, sql1) {
                    for (i = 0; i < sql1.length; i++) {
                        json.Company.SalesOrders.SalesOrder[i] = {
                            "Id": sql1[i].Id,
                            "AccountReference": sql1[i].AccountReference,
                            "SalesOrderDate": sql1[i].SalesOrderDate,
                            "SalesOrderAddress": [{
                                "Forename": sql1[i].billFirstname,
                                "Lastname": sql1[i].billLastName,
                                "Address": sql1[i].billAddress1
                            }],
                            "SalesOrderItems": {}
                        };
                        json.Company.SalesOrders.SalesOrder[i].SalesOrderItems = getOrderLines(sql1[i].Id);
                    } // End first For loop.
                    res.json(json);
                };
            };
            getOrderLines = function (orderId) {
                var orderLineJson = {
                    "Item": []
                };
                mysql.query('QUERY', function (err, sql2) {
                    for (j = 0; j < sql2.length; j++) {
                        orderLineJson.Item[j] = {
                            "SKU": sql2[j].name,
                            "QtyOrdered": sql2[j].quantity,
                            "UnitPrice": sql2[j].price
                        };
                    }
                });
                return orderLineJson;
            };

2 个答案:

答案 0 :(得分:1)

在处理异步操作时,不能使用return。我建议学习和练习承诺。起初它们有点难以理解,但一旦点击,我认为你会更喜欢它们继续传递,你可以从那里去。

目前,您需要学习使用回调。 Promise仍然使用回调。将回调传递给异步函数,并在异步操作完成后调用它:

function getOrderLines(orderId, cb) {
    mysql.query('QUERY', function (err, sql2) {
        // handle err

        cb(/* processed data */)
    });
}

您在调用getOrderLines时传递了该回调,这允许您使用传递给它的值:

getOrderLines(sql1[i].Id, function (err, result) {
    res.json(result);
});

答案 1 :(得分:0)

getOrderLines是一个asyntask,调用这种方式将返回空数组

var async = require('async');

router.get('/salesOrders', function(req, res) {

  // your object here
  var json = {
    Company:{
      SalesOrders: {
        SalesOrder: []
      }
    }
  }; 

  var getSalesOrder = function(callback){
    mysql.query("QUERY", function(err, sql1) {
      for (var i = 0; i < sql1.length; i++) {

        // push item into array
        json.Company.SalesOrders.SalesOrder.push({
          "Id": sql1[i].Id,
          "AccountReference": sql1[i].AccountReference,
          "SalesOrderDate": sql1[i].SalesOrderDate,
          "SalesOrderAddress": [{
            "Forename": sql1[i].billFirstname,
            "Lastname": sql1[i].billLastName,
            "Address": sql1[i].billAddress1
          }],
          "SalesOrderItems": {}
        });
      }

      // job done, trigger next function;
      callback();
    });
  }

  var getOrderLines = function(callback) {
    var orderLineJson = {"Item":[]};
    var dataLength = json.Company.SalesOrders.SalesOrder.length;

    for(var i=0; i<dataLength; i++){

      // do what ever you like with orderId
      var orderId = json.Company.SalesOrders.SalesOrder[i].Id;

      // async query
      mysql.query('QUERY', function(err, sql2) {
        for (var j = 0; j < sql2.length; j++) {
          orderLineJson.Item.push({
            "SKU": sql2[j].name,
            "QtyOrdered": sql2[j].quantity,
            "UnitPrice": sql2[j].price
          });
        }

        json.Company.SalesOrders.SalesOrder[i].SalesOrderItems = orderLineJson;

        // check for the last item
        if(i == dataLength-1)
          callback();
      });
    }
  }

  // run async sequentially
  async.series([getSalesOrder, getOrderLines], function(err, result){
    // finally send the json
    res.json(json);
  });
});

使用异步模块

{{1}}