如何从mssql多层嵌套回调中获取recordset返回值?
解决mssql深层嵌套回调中获取recordset的问题
你当前的代码存在核心问题:doQuery是async函数,但内部没有返回任何异步操作的结果——嵌套回调里的return recordset仅在ps.unprepare的回调函数内生效,无法传递到doQuery外层,因此await doQuery()最终会拿到undefined。
下面提供两种可靠的解决方案:
方案一:使用mssql原生Promise API(推荐)
mssql的绝大多数方法都支持Promise调用,完全可以摆脱嵌套回调,用async/await实现线性异步流程:
let storedRecordset = await doQuery(); async function doQuery() { const ps = new sql.PreparedStatement(/* [pool] */); ps.input('param', sql.Int); try { await ps.prepare('select @param as value'); const result = await ps.execute({ param: 12345 }); await ps.unprepare(); return result; // 直接返回结果,外层await可获取 } catch (err) { console.error('查询执行失败:', err); throw err; // 抛出错误供外层处理 } }
这种写法不仅消除了嵌套回调,还能通过try/catch统一捕获所有异步操作的错误,代码可读性和维护性大幅提升。
方案二:手动封装Promise(兼容特殊场景)
如果需要适配旧版本代码或特殊业务场景,可以手动将每个回调式方法封装为Promise:
let storedRecordset = await doQuery(); async function doQuery() { const ps = new sql.PreparedStatement(/* [pool] */); ps.input('param', sql.Int); // 封装prepare为Promise await new Promise((resolve, reject) => { ps.prepare('select @param as value', err => err ? reject(err) : resolve()); }); // 封装execute为Promise并获取结果 const result = await new Promise((resolve, reject) => { ps.execute({ param: 12345 }, (err, res) => err ? reject(err) : resolve(res)); }); // 封装unprepare为Promise await new Promise((resolve, reject) => { ps.unprepare(err => err ? reject(err) : resolve()); }); return result; }
核心思路是用Promise包裹每个异步回调,将回调式的异步操作转换为可通过await等待的形式,从而避免嵌套并正确传递结果。
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

