以asynchronous方式在node.js中查询数据库

我想弄清楚正确的方式来asynchronous调用一个函数,如果它也正在对数据库进行asynchronous调用。

在我的代码中,我调用了一个名为“check_foods()”的函数,如果它尚未被调用,它将查询数据库最多两次。 数据库查询将填充两个variables蔬菜和水果(假设他们还没有被填充)。 一旦函数返回,我想使用这些variables。

不过,我认为现在我的代码的方式,即使它还没有从数据库中提取数据,它将尝试开始处理两个console行。 我是否正确的这个假设? 如果是这样,我该怎么做才能正确实施?

我的代码的简化版本如下所示:

 var vegetables = {}; var fruit = {}; async function starter (){ sql = "select growth_items from garden where room_id = ?"; db_connection.query(sql, [socket.room], function (err, result){ if (err){ console.log("Garden Error: " + err); return; } console.log(result); check_foods(); //Should not get to this point until variables have been populated //However, due to the async nature of the code this does not seem to be implemented correctly. //process vegetables[socket.room] and fruit[socket.room] console.log(vegetables[socket.room]); console.log(fruit[socket.room]); }); } async function check_foods(){ //Check to see if vegetables[socket.room] already exists, otherwise load it from the database if (typeof vegetables[socket.room] !== "undefined"){ sql = "select name, qty from vegetables where room_id = ?"; db_connection.query(sql, [socket.room], function (err, result){ if (err){ console.log("An vegetable error has occurred: " + err); return; } vegetables[socket.room] = result; }); }; //Check to see if fruit already exists before looking up again if (typeof fruit[socket.room] !== "undefined"){ sql = "select name, qty from fruit where room_id = ?"; db_connection.query(sql, [socket.room], function (err, result){ if (err){ console.log("An fruit error has occurred: " + err); return; } fruit[socket.room] = result; }); }; } 

对于像这样的项目来说,将所有东西都分解成小单元是非常有用的。 这样一来,asynchronous部分就可以被包含或者以一种更易于推理的方式来承诺。 它看起来像你想使用async/await这是很好的,但这意味着你需要产生承诺。 上次我检查标准的MySQL库没有这样做,但是很容易包装它们。

所以我会打破这个这样的:

 function check_growth_items(room){ //simple function to get growth items return new Promise((resolve, reject) => { sql = "select growth_items from garden where room_id = ?"; db_connection.query(sql, [room], function (err, result){ if (err){ console.log("Garden Error: " + err); reject(err); } resolve(result) }) }) } function get_food(type, room_id){ // expects a type [vegetable | fruit] and room return new Promise((resolve, reject) => { sql = "select name, qty from ? where room_id = ?"; db_connection.query(sql, [type, room_id], function (err, result){ if (err){ console.log("An vegetable error has occurred: " + err); reject(err); } resolve(result); }); }) } 

现在所有的asynchronous事情都很简单。 在一个asynchronous函数中,你可以调用类似于:

 let items = await check_growth_items(socket.room) 

或拿到食物:

 fruit[socket.room] = await get_food('fruit',socket.room ) 

要么

 get_food('fruit',socket.room ) .then(result => fruit[socket.room] = result) .catch(err => console.log(err)) 

我承认,不是100%确定你最终的代码应该做什么,但你的主要function应该能够看起来像这样:

 async function starter (){ // it's not clear in your code how you're using this // of it the other async calls depend on the return value var growth_items = await check_growth_items(socket.room) if (!vegetables[socket.room]) { vegetables[socket.room] = await get_food('vegetables',socket.room ) } if (!fruit[socket.room]) { fruit[socket.room] = await get_food('fruit',socket.room ) } console.log(vegetables[socket.room]); console.log(fruit[socket.room]); } 

这可能不是一个剪切和粘贴的解决scheme,但希望能给你一些更好的方法来组织的想法。

您可以使用promisifycallback转换为promise ,然后使用await

示例代码应该是这样的

 const vegetables = {}; const fruit = {}; const Promise = require('bluebird'); // or you can use node utility module as well const db = Promise.promisifyAll(require('YOUR DB LIB')); const db_connection = 'YOUR DB CONNECTION' async function starter (){ const SQL = "select growth_items from garden where room_id = ?"; try { const result = await db_connection.query(SQL); console.log(result); check_foods(); } catch(err) { console.log("Garden Error: " + err); } } async function check_foods(){ //Check to see if vegetables[socket.room] already exists, otherwise load it from the database if (typeof vegetables[socket.room] !== "undefined"){ const SQL = "select name, qty from vegetables where room_id = ?"; try { const result = await db_connection.query(SQL); vegetables[socket.room] = result; } catch(err) { console.log("An vegetable error has occurred: " + err); return; } } //Check to see if fruit already exists before looking up again if (typeof fruit[socket.room] !== "undefined"){ const SQL = "select name, qty from fruit where room_id = ?"; try { const result = await db_connection.query(SQL); fruit[socket.room] = result; } catch(err) { console.log("An fruit error has occurred: " + err); return; } }; }