You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:42:36