2012-12-29 116 views
0

我是一个nodejs新手,习惯了所有异步的东西。Nodejs MySQL查询块请求模块

使用: - 节点的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 BEFORE AFTER www.yahoo.com BEFORE AFTER www.cnn.com BEFORE AFTER ...但是在查询完成之前没有“INSIDE”。

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

回答

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事件将花费相当长的时间(即使只有一两毫秒),因为它必须与Google或雅虎或任何人建立连接。

输出:

$ 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) 
+0

感谢这么多的响应。 – umutm

+0

非常感谢回复。但不完全相信如果是这样的话(它也可以)。 console.log()需要15秒钟才能从查询中打印URL,并且在此期间不会打印“INSIDE”。但是,我想知道这是否可以是一个性能问题与console.log()是同步。尽管更新的代码似乎工作,它会跳过(明白它可以是唯一的文本环境)你的MySQL查询部分可能是有问题的部分(我也认为不是)。 – umutm

+0

实际上,在写作时,你的结果听起来更合理。 将回来更多的测试。 再次非常感谢(如果是这种情况,我会很乐意接受答案)。 – umutm