node.js - Nodejs - 不确定如何在函数中等待数据库查询
问题描述
我是 nodejs 的新手,正在努力掌握 async/await 功能。我已经阅读了许多其他 SE 帖子和许多博客,但似乎无法获得正确的代码组合来实现预期的程序流程。
我的程序的总体思路是调用 startNextPick() 函数,然后调用 getLeagueFromDraftPicks()。此函数内部是一个查询,需要“等待”才能完成,但我不确定执行此操作的正确/简单方法。目前,没有等待导致函数返回“未定义”结果。在这种情况下等待查询响应的正确/简单方法是什么?
startNextPick();
async function startNextPick(pickId) {
console.log('A-- starting next pick');
var leagueId = await getLeagueFromDraftPick(pickId);
console.log('B-- leagueId from getLeagueFromDraftPick: '+leagueId);
leagueId = Number(leagueId);
if (leagueId > 0) {
//.... do other stuff here
} else {
console.log('Error with finding league based on draft pick');
}
}
async function getLeagueFromDraftPick(pickId) {
pickId = Number(pickId);
var leagueId;
console.log('1 pickId: '+pickId);
if (pickId <= 0) {
return false;
}
// Get LeagueID from draft based on pickId
// *** Need to "await" this query "
connection.query('select LEAGUE_ID from DRAFT where ID=? limit 1',
[pickId],
function (error, results, fields) {
if (error) {
console.log(error);
return false;
} else {
leagueId = results[0].LEAGUE_ID;
console.log('2-- pickId: '+pickId);
console.log('3-- leagueId: '+leagueId);
return leagueId;
}
});
console.log('4-- leagueId: '+leagueId);
return leagueId;
}
使用 console.log 跟踪代码的时间和流程,很明显需要等待查询,因为 getLeagueFromDraftPick() 的返回值显示未定义,但查询结果最终显示正确。
Console.log output
****starting next pick****
A-- starting next pick
1 pickId: 19002
4-- leagueId: undefined
B-- leagueId from getLeagueFromDraftPick: undefined
Error with finding league based on draft pick
2-- pickId: 19002
3-- leagueId: 52
** 解决方案 ** 使用@cyberwombat 回答并进行一些修改,我能够让它工作。下面是工作代码:
async function startNextPick(pickId) {
console.log('A-- starting next pick');
var leagueId = await getLeagueFromDraftPick(pickId);
console.log('B-- leagueId from getLeagueFromDraftPick: '+leagueId);
}
async function getLeagueFromDraftPick(pickId) {
pickId = Number(pickId);
console.log('1 pickId: '+pickId);
if (pickId <= 0) {
return false;
}
// Get LeagueID from draft based on pickId
// *** Need to "await" this query "
const leagueId = await new Promise(function(resolve, reject) {
connection.query('select LEAGUE_ID from DRAFT where ID=? limit 1',
[pickId],
function (error, results, fields) {
if (error) {
console.log(error);
reject(error);
} else {
if (results[0]) {
console.log('2-- pickId: '+pickId);
console.log('3-- leagueId: '+results[0].LEAGUE_ID);
resolve(results[0].LEAGUE_ID);
} else {
resolve(0); }
}
});
});
console.log('4-- leagueId: '+leagueId);
return leagueId;
}
Console output:
****starting next pick****
A-- starting next pick
1 pickId: 19031
2-- pickId: 19031
3-- leagueId: 52
4-- leagueId: 52
B-- leagueId from getLeagueFromDraftPick: 52
解决方案
连接位使用回调。为了让你的 async/await 可以很好地工作,你可以将它包装在一个 Promise 中(你也可以查看那个 db 库是否有一个 Promisified/async 版本)。理想情况下,您希望将其包装在 try/catch 块中以处理错误,但这是一个不同的故事。这是返回1eagueId
异步的代码。
async function getLeagueFromDraftPick(pickId) {
pickId = Number(pickId);
var leagueId;
console.log('1 pickId: '+pickId);
if (pickId <= 0) {
return false;
}
const leagueId = await new Promise(function(resolve, reject) {
// Get LeagueID from draft based on pickId
// *** Need to "await" this query "
connection.query('select LEAGUE_ID from DRAFT where ID=? limit 1',
[pickId],
function (error, results, fields) {
if (error) {
console.log(error);
reject(error)
} else {
leagueId = results[0].LEAGUE_ID;
console.log('2-- pickId: '+pickId);
console.log('3-- leagueId: '+leagueId);
resolve(leagueId)
}
});
})
console.log('4-- leagueId: '+leagueId);
return leagueId;
}
简化的可运行示例:
// Create our async function
async function getLeagueFromDraftPick() {
console.log('1')
// We can use the new Promise to wrap old style callbacks - not shown here
const leagueId = await new Promise((resolve, reject) => {
console.log('2')
// Fake some delay - i.e. pretend w are doing some http request
setTimeout(() => {
resolve('foo')
}, 1000);
})
console.log('3')
return leagueId
}
// This weird parenthesis setup is just a trick to run async functions from the console
(async () => {
const leagueId = await getLeagueFromDraftPick()
console.log(leagueId)
})()
推荐阅读
- tensorflow - 无法在 python 3.9 上安装 tensorflow
- android - 使用 Visual Studio 2019 让 ADB 在 Pixel 5 / Android 11 上工作
- javascript - HTML拖放,dragover事件返回子元素而不是父元素
- reactjs - React - 如何将流类型分配给导出的模块?
- python - AttributeError:“Line2D”对象没有属性“cmap”
- excel - Visual Basic excel vba字符串中最大的数据类型失败
- reactjs - 反应原生的布尔文本输入
- arrays - 尝试使用 image-proc 工具箱中的 regionprops 测量高尔夫球的直径
- list - Flutter calendar Firestore“类型'QuerySnapshot'不是'List'类型的子类型
'" - reactjs - 检查网络响应能力的最佳方法