Node.js 异步执行时间过长

Node.js async taking too long to execute

我有一系列查询

var array = [ 'UPDATE EVALUATION SET mark = "16" WHERE id_eval = "21" AND id_usr = "125"', 
              'UPDATE EVALUATION SET mark = "9" WHERE id_eval = "22" AND id_usr = "125"', 
              'UPDATE EVALUATION SET mark = "8" WHERE id_eval = "34" AND id_usr = "125"' 
            ]

但是,当我尝试使用异步同时执行它们时,我的网页显示 Waiting for localhost... 并且它一直在加载。我做错了什么?

async.forEach(array, function(query, callback) {
    connection.query(query, function(err, rows, fields) {
        if(err) {
            return console.error(err);
        }

        callback();
    });
}, function(err){
    if(err) {
        return console.log(err);
    }
});

通常你有这样一个请求处理程序:

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

您的浏览器保持连接,直到 res.end 被调用!

在您的环境中它应该看起来像

const server = http.createServer((req, res) => {

  // ... 
  async.forEach(array, function(query, callback){
    connection.query(query, function(err, rows, fields) {
        // you may do some work here but leave it *alyways* via callback!
        callback(err);
    });
  }, function(err){
    if(err){ // this may be errors from above
      return console.log(err);
    }
    // Exit here !
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('All done.\n');
  });
});

...或更清洁一些

function doSomeDatabaseUpdates(onFinished) {
  var array = [...];
  async.forEach(array, function(query, callback){
    connection.query(query, function(err, rows, fields) {
        // you may do some work here but leave it *alyways* via callback!
        callback(err);
    });
  }, 
  function IGetCalledAfterAboveCallbackWereExecuted(err){
    if(err){ // this may be errors from above
      return console.log(err);
    }
    // Exit here !
    onFinished();
  });
}


const server = http.createServer((req, res) => {

  // ... do some work

  if (doSomeUpdated === true) {
    doSomeDatabaseUpdates(function calledAfterUpdates() {
      res.end("updates something");
    });
  } else {
    res.end("nothing to do");
  }

});

只需确保您 return 调用 forEach 回调后的响应:

async.forEach(array, function(query, callback) {
    connection.query(query, function(err, rows, fields) {
        if(err) {
            console.error(err);
        }

        callback();
    });
}, function(err){
    if(err) {
        console.log(err);
    }

    res.redirect('/next-page');
});

这样,重定向只会在所有查询结束时发生。

您应该验证的一些事项:

  • 确认您没有在上述代码之前调用 res.end()res.redirect() 或任何类似的东西。
  • 验证您的数据库 query 方法实际上只需要 2 个参数:查询和回调,而不是介于两者之间的任何参数(例如查询参数)。
  • 验证这段代码确实在您期望的时候被调用。尝试一路调试请求。
  • 目前这里没有真正的错误处理。如果出现问题,您应该考虑 returning 一个 HTTP 错误。这也应该有助于您将来调试此代码。