2015-05-03 165 views
2

我遇到了問題,即使數據庫函數沒有返回值,也無法繼續進行數據庫調用。節點JS異步數據庫調用

這裏是基本的HTTP服務器代碼:

var http = require('http'); 

http.createServer(function (request, response) { 

response.writeHead(200, { 
    'Content-Type': 'text/plain', 
    'Access-Control-Allow-origin': '*' // implementation of CORS 
}); 

response.end("ok"); 
; 
}).listen(8080,'0.0.0.0'); 

使用request.on(「數據」)的功能,我能夠從JSON解碼的請求,並繼續,爲了使數據庫調用:

request.on('data', function (chunk) { 
    var json = JSON.parse(chunk); 
    var id = parseInt(json["id"]); 
    response.end(callDatabase(id)); 
}); 

數據庫功能是這樣的:

function callDatabase(id) { 
    var result; 
    var connection = mysql.createConnection(
     { 
      host  : '192.168.1.14', 
      user  : 'root', 
      password : '', 
      database : 'test' 
     } 
    ); 

    connection.connect(); 
    var queryString = 'SELECT name FROM test WHERE id = 1'; 

    connection.query(queryString, function(err, rows, fields) { 
     if (err) throw err; 

     for (var i in rows) { 
      result = rows[i].name; 
     } 
    }); 
    connection.end(); 
    return result; 
    } 
} 

然而在測試中,這證明我做錯了。我知道我可能想要使用節點異步模塊,我已經厭倦了。我也嘗試使用瀑布方法,以及在線並行和許多其他教程。我覺得request.on函數應該是並行的,然後是數據庫調用異步,所以雖然節點正在等待來自數據庫服務器的響應,但它可以自由地處理任何其他請求,使排隊時間最短。

請告訴我,如果我錯過了解節點js的任何概念。

+0

不能從異步函數返回,你必須使用一個回調,然後將'該回調內部response.end'等 – adeneo

+0

有什麼地方在線,我可以看到一個使用回調和返回值的例子嗎? –

回答

6

您正在返回result並在查詢從db返回值之前關閉連接。將該代碼放入回調中。

修復你的代碼,它應該是這樣的:

function callDatabase(id) { 
    var result; 
    var connection = mysql.createConnection(
     { 
      host  : '192.168.1.14', 
      user  : 'root', 
      password : '', 
      database : 'test' 
     } 
    ); 

    connection.connect(); 
    var queryString = 'SELECT name FROM test WHERE id = 1'; 

    connection.query(queryString, function(err, rows, fields) { 
     if (err) throw err; 

     for (var i in rows) { 
      result = rows[i].name; 
     } 

     connection.end(); 
     return result; 
    }); 
} 

雖然,這將只解決問題的一部分,因爲現在你還在等待查詢的響應之前調用response.end(callDatabase(id));

爲了解決這個問題,你需要返回某種回調。

function callDatabase(id, callback) { 
    // the method code here... 
    connection.query(queryString, function(err, rows, fields) { 
     // code... 

     // instead of returning the result, invoke the callback! 
     callback(rows); 
    }); 
} 

現在你可以這樣調用:

request.on('data', function (chunk) { 
    var json = JSON.parse(chunk); 
    var id = parseInt(json["id"]); 
    callDatabase(id, function(res) { 
     response.end(res); 
    }); 
}); 
+2

非常感謝!只是出於好奇心,爲了性能......服務器應該連接到數據庫服務器嗎?在每個http請求之後關閉連接是否浪費性能? –