2016-01-22 193 views
0

我试图让我的头绕着node.js的异步本质。 我有一个明确的路线,我知道不会给我需要的数据。基本上,第一个mysql查询按预期工作100%,并且在res.json中返回的json数据是正确的。然而,在第一个mysql函数中,我调用了另一个函数'getOrderLines()',它总是返回'{“Item':[]}',而不是我期望的数据。Node.js处理异步

我知道这是因为节点的异步性质而发生的,但是我似乎无法解决这个问题,我查看了承诺并编写了一些基本的承诺,但无法使其适用于以下。

任何帮助,将不胜感激。

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

在处理异步操作时,不能使用return。我会推荐学习和实践的承诺。起初他们有点难以理解,但一旦点击,我认为你会喜欢他们继续传球,你可以从那里出发。

现在,您需要学习如何使用回调。承诺仍然使用回调。传递回调到异步函数并调用它时,它的异步操作完成:

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); 
}); 
0

getOrderLines是asyntask,调用此方法将返回空数组

..SalesOrderItems = getOrderLines(sql1[i].Id); 

使用异步模块

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