从回调中调用函数会导致节点应用挂起

Calling a function from within a callback causes node app to hang

本文关键字:节点 应用 挂起 回调 调用 函数      更新时间:2023-09-26

我已经用实际代码更新了帖子。

问题是节点应用程序挂起并且不会退出,除非我在 addArticle 中注释掉查询。我想知道我在这里做错了什么(关于悬挂问题)。

function addArticle(title, text, date, link) {
  connection.query("SELECT * FROM articles WHERE link LIKE "+connection.escape(link), function(error, rows, fields) {
    if(rows.length == 0) {
      console.log("article not in database");
      console.log(connection.escape(title));
      var values = [connection.escape(title), connection.escape(text), date, connection.escape(link), '{}'];
      connection.query("INSERT INTO articles (title, text, date, link, topics) VALUES ?", [[values]], function(err) {
        if(err) throw err; 
      });
    }
  });
}
function scrapeReuters() {
  var url = 'http://www.reuters.com/news/archive/technologyNews?date=10092013';
  request(url, function(err, resp, body){
      $ = cheerio.load(body);
      links = $('a');
      $(links).each(function(i, link){
        var addr = $(link).attr('href');
        if(addr != undefined && addr.indexOf('article') != -1 && addr.indexOf('http') == -1 ) { 
          var full_link = "http://www.reuters.com"+addr;
          var title = $(link).text();  
          request(full_link, function(err, resp, body){
            $ = cheerio.load(body);
            para = $('p').text();
            addArticle(title, para,new Date().getTime(), full_link);
          }); 
        }   
      }); 
  }); 
}

您可能需要在所有查询完成后关闭连接。可以尝试使用 https://github.com/caolan/async 库按顺序运行查询,然后在主回调中关闭连接。

这有点棘手,但首先你需要定义一个要执行的函数数组。然后运行 async.sequence(arrayOfFns,masterCallback)。主回调获取错误和结果(注意复数,它来自所有函数)。在该主回调中,终止 mysql 连接/和/或结束进程。

为此,我将重写 addArticle 查询以仅返回查询字符串。然后在你的$(links).each循环之前,我会制作一个名为toInsert的数组

在每个循环中,我会说

toInsert.push(function(callback) {
    connection.query(addArticle(...),function(err) {
         if(err) callback(err);
         else callback(null,true);
    });
});

然后在循环运行后

 async.sequence(toInsert,function(errs,results) {
      connection.close() //not sure if correct
      process.exit(); //maybe, if needed?
 });