2012-12-29 165 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