如何让Node.js等待外部JS文件中异步函数执行完成并获取结果
解决Node.js异步函数等待问题
首先,问题的核心是你调用的patientId函数内部执行的是异步数据库查询操作,函数本身在异步操作完成前就已经执行完毕,自然返回undefined。下面给你几种常见的解决方式:
方法1:使用回调函数(传统异步处理方式)
修改你的patientId函数,让它接受一个回调参数,在异步查询完成后通过回调返回结果:
const patientId = function(patientUUID, callback) { var mysql = require('mysql'); var connectionF = mysql.createConnection({ host : 'localhost', user : 'localuser', password : 'localpass', database: 'localdb' }); connectionF.connect(); connectionF.query(patientIDFinderQuery, [patientUUID], function(error, result, fields) { if (error) { // 把错误也通过回调传递出去 return callback(error); } // 成功时传递结果 callback(null, result[0].patient_id); // 记得关闭连接 connectionF.end(); }); }
然后在调用的时候,通过回调获取结果:
app.post('/pushdata', function (req, res,next) { connection.query(creatorQuery, [login], function(error,result,fields) { if (error) { // 处理查询错误 return res.status(500).json({status: 'error', message: error.message}); } let visit = req.body.visits[0] let patientUUID = visit.patient dbHelper.patientId(patientUUID, function(err, patientId) { if (err) { return res.status(500).json({status: 'error', message: err.message}); } console.log(patientId); // 现在能拿到正确结果了 // 这里可以继续后续逻辑,比如用patientId做其他操作 res.json({'status':'ok'}) }); }); })
方法2:使用Promise + Async/Await(现代推荐方式)
这种方式的代码可读性更强,写法更接近同步逻辑:
首先把patientId封装成返回Promise的函数:
const patientId = function(patientUUID) { return new Promise((resolve, reject) => { var mysql = require('mysql'); var connectionF = mysql.createConnection({ host : 'localhost', user : 'localuser', password : 'localpass', database: 'localdb' }); connectionF.connect(); connectionF.query(patientIDFinderQuery, [patientUUID], function(error, result, fields) { connectionF.end(); // 关闭连接 if (error) { return reject(error); // 错误时reject } resolve(result[0].patient_id); // 成功时resolve结果 }); }); }
然后在调用的地方使用async/await,注意要把外层的回调函数改成async函数:
app.post('/pushdata', async function (req, res,next) { try { // 用await等待creatorQuery的异步结果 const creatorResult = await new Promise((resolve, reject) => { connection.query(creatorQuery, [login], function(error, result, fields) { if (error) reject(error); else resolve(result); }); }); let visit = req.body.visits[0] let patientUUID = visit.patient let patientId = await dbHelper.patientId(patientUUID); // 等待patientId的结果 console.log(patientId); // 正确获取结果 // 后续逻辑... res.json({'status':'ok'}) } catch (error) { // 统一处理所有异步操作的错误 res.status(500).json({status: 'error', message: error.message}); } })
额外建议
- 每次调用
patientId都创建新的数据库连接不太高效,建议使用mysql连接池来复用连接,提升性能。 - 所有异步操作都要做好错误处理,避免程序崩溃。
内容的提问来源于stack exchange,提问作者Satya
相关产品推荐
相关产品推荐

