如何执行一个又一个查询并处理该数据?

时间:2017-09-02 00:30:57

标签: javascript node.js express asynchronous

我有一个app.get,它将返回客户数据和客户购买。在这个app.get里面,我需要运行两个mysql调用并构建一个数组来传回。

如何逐个执行一个查询并处理该数据?

app.get('/customer', function (req,res) {
    var response1 = [];
    var response2 = [];
    var processedData = [];

        connection.query('QUERY HERE', function(err, rows, fields) {
        if (!err){
              response.push({rows});
        } else {
            res.status(400).send(err);
        }
    });

    //for loop 'response' results and perform another query
     for (var i = 0; i < response1.length; i++) {
         var row = response1[i];
         connection.query('QUERY HERE FOR row.customerid', function(err, rows, fields) {
           if (!err){
              processedData.push({'Customer Name:' : row.customername, 'purchases' : rows});
            } else {
              res.status(400).send(err);
            }
         });
       }


    //Send json back
    res.setHeader('Content-Type', 'application/json');
    res.status(200).send(JSON.stringify(processedData));

});

1 个答案:

答案 0 :(得分:2)

有一个非常方便的名为async.js的模块,它提供了许多用于执行复杂异步操作的函数。特别地,

    当您需要将一个异步操作/任务的结果传递给另一个时,
  • async.waterfall()非常棒。

  • 当您需要使用异步操作/任务数组的结果创建新数组时,
  • async.mapSeries()非常棒。

让我们两个使用。

如果我正确理解您的代码,代码看起来与

类似
app.get('/customer', function (req, res) {
    async.waterfall([
        // each task is passed a callback 'cb' as last argument;
        // you MUST call it at least and at most once within each task;
        // if you pass an error into the callback as the first argument, it will stop the async function
        function task1 (cb1) {
            //connection.query('QUERY HERE', function(err, rows, fields) {
            //    if (err) return cb1(err);  // stop waterfall() if an error occurred
            //    cb1(null, rows, fields);   // pass results down to next task
            //});

            connection.query('QUERY HERE', cb1); // shorter version
        },
        function task2 (rows, fields, cb2) {

            // iterate and run async operation over each element in array 'rows'
            async.mapSeries(rows, function getPurchases (row, cb3) {
                connection.query('QUERY HERE FOR row.customerid', function (err, purchases, fields) {
                    if (err) return cb3(err);  // stop mapSeries() if an error occurred
                    cb3(null, { 'Customer Name': row.customername, 'purchases': purchases })
                });
            }, function (err, customers) {
                // when mapSeries() is done iterating OR if an error occurred, it will come here

                if (err) return cb2(err); // stop waterfall() if an error occurred 
                cb2(null, customers)
            });

        // }, cb2); // shorter version

        }
    ], function (err, customers) {
        // when waterfall() is done all its tasks OR if an error occurred, it will come here

        // handle error and send response here
    });
});