Nodejs MySQL查询阻止请求模块

时间:2012-12-29 15:47:20

标签: mysql node.js httprequest

我是一个节点新手,并习惯了所有异步的东西。

使用:   - Node-MySQL(https://github.com/felixge/node-mysql)   - 请求(https://github.com/mikeal/request) 模块现在。

我正在查询大量的URL(10,000个URL),并尝试向他们发送HTTP GET请求以获取其HTTP状态。

它可以工作,但问题是,当我运行代码时,当返回MySQL查询的每一行时,调用processURL函数,它会在每个URL值之后记录'BEFORE'和'AFTER',(据我所知)发送HTTP请求,但在返回HTTP状态之前等待MySQL查询完成。

简单地说,在查询运行时,它无法检查这些URL并返回其结果。它等待查询完成以返回HTTP请求的结果。

这对我来说没什么意义,因为它在流每一行时运行processURL函数。这是完整的代码:

var mysql       = require('mysql');

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'root',
  password : '',
  database : 'urlDB',
});

var query = connection.query('SELECT * FROM urls LIMIT 10000');
query.on('error', function(err) {
    console.log(err);
})
query.on('result', function(row) {
    processURL(row.urlValue, function() {

    });
    console.log(row.urlValue);
})

function processURL (url){
    var request     = require('request');
    var startTime = new Date();
    console.log('BEFORE');
    request({
        uri: url,
        method: 'GET',
    }, function(error, response, body) {
        console.log('INSIDE');
        var endTime = new Date();

        if (!error) {
            console.log(response.statusCode + '  Start: ' + startTime + '  End: ' + endTime);
        } else {
            console.log('timeout');
        }
    })
    console.log('AFTER');
}

输出如下: www.google.com 之前 后 www.yahoo.com 之前 后 www.cnn.com 之前 后 ...但在查询完成之前没有'INSIDE'。

非常感谢任何帮助。非常感谢。

1 个答案:

答案 0 :(得分:0)

我修改了您的示例以更慢地获得结果,并且它按预期工作。您可以复制粘贴以尝试:

var request = require('request');

var urls = ['http://google.com', 'http://yahoo.com', 'http://ninjaturtles.com'];

getResultSlowly();

function getResultSlowly() {
  var result = urls.shift();
  if (!result) return;

  console.log(result);
  processUrl(result);
  setTimeout(getResultSlowly, 1000);
}

function processUrl(url) {
  var startTime = new Date();
  console.log('BEFORE');
  request({
    uri: url,
    method: 'GET',
  }, function(error, response, body) {
    console.log('INSIDE');
    var endTime = new Date();

    if (!error) {
      console.log(response.statusCode + '  Start: ' + startTime + '  End: ' + endTime);
    } else {
      console.log('timeout');
    }
  })
  console.log('AFTER');
}

网络延迟可能只是掩盖了异步行为。

您的查询结果将立即返回,一旦您执行代码,就会触发多个result事件。但是,您的request事件需要花费更长的时间(即使只是一毫秒或两秒),因为它必须与谷歌或雅虎或任何人建立联系。

输出:

$ node asynctest.js 
http://google.com
BEFORE
AFTER
INSIDE
200  Start: Sat Dec 29 2012 11:31:34 GMT-0500 (EST)  End: Sat Dec 29 2012 11:31:34 GMT-0500 (EST)
http://yahoo.com
BEFORE
AFTER
http://ninjaturtles.com
BEFORE
AFTER
INSIDE
200  Start: Sat Dec 29 2012 11:31:36 GMT-0500 (EST)  End: Sat Dec 29 2012 11:31:37 GMT-0500 (EST)
INSIDE
200  Start: Sat Dec 29 2012 11:31:35 GMT-0500 (EST)  End: Sat Dec 29 2012 11:31:38 GMT-0500 (EST)