Node.js中TypeScript控制器调用服务后数据无法传递至Marko视图的问题排查
问题原因与解决方案
你遇到的问题核心在于异步操作的返回值没有被正确传递给模板渲染逻辑,具体来说是getInfo方法的设计和调用方式存在问题:
为什么info属性没出现在视图里?
- 同步函数无法返回异步结果:你的
getInfo是同步函数(返回类型为void),但内部使用了async.parallel这个异步操作。当你给dataView.info赋值时,getInfo会立刻返回undefined,而async.parallel的回调函数(拿到responses的逻辑)是在后续事件循环中才执行的——这时候模板早已渲染完成,自然拿不到info数据。 - 回调函数的使用错误:你在
async.parallel的错误分支里调用了callback(err),但这个callback并没有和渲染逻辑的流程正确关联,getInfo也没有通过这个回调把异步结果传递出去。
修复方案
我们需要把异步逻辑改成Promise风格,配合async/await确保模板渲染前能拿到完整的info数据:
1. 重构getInfo为异步函数
把async.parallel包裹在Promise中,让它可以通过await获取结果:
// 改成async函数,返回Promise类型的结果 const getInfo = async (req: Request | any, reply: any): Promise<{ personalData: any, addionalInfo: any }> => { const headers = helpers.setHeaders(req); const idNumber = req.yar.get('idNumber'); return new Promise((resolve, reject) => { async.parallel({ personalData: (callback) => infoService.personalInfo(idNumber, headers, callback), addionalInfo: (callback) => infoService.addicionalInfo(headers, callback), }, (err, responses) => { if (err) { // 把错误抛出去,让外层的try/catch处理 reject(err); } else { console.log("response", responses); // 把异步结果返回 resolve(responses); } }); }); };
2. 修改renderRecoveryData为异步handler
Hapi的路由handler支持异步函数,我们可以用await等待getInfo的结果,再执行模板渲染:
// 改成async函数,处理异步逻辑 export const renderRecoveryData = async (req: Request | any, reply: ResponseToolkit): Promise<void> => { try { // 等待getInfo拿到异步结果 const info = await getInfo(req, reply); const dataView: { [key: string]: any } = { id: 1, info: info, // 现在这里的info是正确的异步结果 }; // 拿到数据后再渲染模板 templateEngine.renderFromTemplate("./views/private/info/info.marko", dataView, req, reply); } catch (err) { // 统一处理错误,比如返回500状态码 reply.code(500).send(err); } };
3. 移除无用的callback参数
原来的renderRecoveryData和getInfo里的callback参数已经不需要了,async/await+Promise的异步流程比回调风格更清晰易维护。
这样修改后,模板渲染前会确保info数据已被正确获取,视图里就能正常看到info属性了。
内容的提问来源于stack exchange,提问作者Eladerezador
相关产品推荐
相关产品推荐

