2016-01-22 242 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); 
    }); 
});