【问题标题】:Node.js Dealing with AsyncNode.js 处理异步
【发布时间】:2016-04-29 07:42:53
【问题描述】:

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

我知道这是因为节点的异步性质而发生的,但是我似乎无法解决这个问题,我已经研究了 Promise 并编写了一些基本的 Promise,但无法让它在下面工作。

任何帮助将不胜感激。

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

【问题讨论】:

    标签: javascript mysql json node.js asynchronous


    【解决方案1】:

    处理异步操作时不能使用return。我建议学习和实践 promises。一开始它们有点难以理解,但一旦点击,我想你会更喜欢它们而不是继续传递,你可以从那里开始。

    现在,您需要学习使用回调。 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);
    });
    

    【讨论】:

      【解决方案2】:

      getOrderLines 是一个异步任务,这样调用会返回空数组

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

      【讨论】:

        猜你喜欢
        • 2012-12-27
        • 1970-01-01
        • 2018-01-02
        • 2017-02-26
        • 2019-03-21
        • 2014-04-10
        • 2011-08-14
        • 1970-01-01
        相关资源
        最近更新 更多