簡體   English   中英

Node.js處理異步

[英]Node.js Dealing with Async

我正在設法弄清node.js的異步特性。 我有一條明確的路線,在該路線下,我不會提供所需的數據。 本質上,第一個mysql查詢可以按預期的100%進行工作,並且在res.json中返回的json數據是正確的。 但是,在第一個mysql函數中,我調用了另一個函數'getOrderLines()',該函數始終返回'{“ Item”:[]}',而不是我期望的數據。

我知道這是由於節點的異步性質而發生的,但是我似乎無法解決這個問題,我已經研究了promises並寫了一些基本的promises,但是不能使它在下面工作。

任何幫助,將不勝感激。

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

處理異步操作時,不能使用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);
});

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM