【问题标题】:How can I execute one query after another and process that data?如何执行一个又一个查询并处理该数据?
【发布时间】:2018-02-11 01:28:31
【问题描述】:

我有一个 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));

});

【问题讨论】:

  • 在 if 块中添加你的循环和第二个查询。顺便说一句,在 JS 中,我们通常使用 if (err) { return res.status(400.send(err) },然后该块之后的任何代码在没有错误并且不需要在块内时执行。不是规则, 稍微干净一点。如果你这样做,你的循环和第二个查询将在 if 块之后。
  • 嗨@Nocturno,添加了我上面的第二个查询以及for循环。语法可能不是 100%,但只是想概述一下我正在努力完成。
  • 是的,我看到了你想要完成的工作,我想在其他人试图说服你使用复杂的异步库之前向你展示标准的异步方式。我想让你看到的是你必须在第一个回调中添加你的循环和第二个查询。该回调仅在异步函数返回后执行。这就是异步行为的工作原理。我将修改您的代码并将其添加为答案。

标签: javascript node.js express asynchronous


【解决方案1】:

有一个名为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
    });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    相关资源
    最近更新 更多