NodeJS中async函数调用ejs.renderFile返回Undefined的解决方法
问题分析与修复方案
你的问题核心在于**ejs.renderFile的回调式写法没有和外层的async函数正确联动**,导致async函数没有返回实际的HTML数据,最终await拿到undefined。
为什么会出现这个问题?
虽然你把makeWeeklyReport声明成了async函数,但里面的ejs.renderFile是基于回调的异步API:你在回调函数里return data,但这个return只是回调函数的返回值,并不会传递到外层的async函数中。外层async函数没有任何return语句,所以默认返回一个状态为resolved、值为undefined的Promise,这就是你await后拿到undefined的原因。
修复方法:将回调式API转为Promise式
Node.js提供了util.promisify工具,可以把基于回调的异步函数转换成返回Promise的版本,这样就能和async/await完美配合。
步骤1:引入util模块并转换renderFile
const util = require('util'); const renderFileAsync = util.promisify(ejs.renderFile);
步骤2:修改makeWeeklyReport函数
async function makeWeeklyReport(meterId, week) { // 从meters中获取仪表 const meter = meters.find(it => it.prm === meterId); const weeklyData = await generateWeeklyGraph(meter, week); try { // 用await等待Promise版本的renderFile完成 const data = await renderFileAsync( path.join(__dirname, './views/partials/', "weekly_graph.ejs"), {} ); console.log(data); // 正常打印HTML内容 return data; // 这里的return会成为async函数返回的Promise的resolved值 } catch (err) { console.log(err); throw err; // 可以选择抛出错误让调用方处理,或者返回默认值 } }
步骤3:调用方式不变(已经是正确的await写法)
data = await makeWeeklyReport(meterId, week); console.log("generated WeeklyReport", data); // 现在能正确输出HTML内容
另一种手动封装Promise的方式(如果不想用util.promisify)
如果你不想用util模块,也可以手动把ejs.renderFile封装成Promise:
async function makeWeeklyReport(meterId, week) { const meter = meters.find(it => it.prm === meterId); const weeklyData = await generateWeeklyGraph(meter, week); return new Promise((resolve, reject) => { ejs.renderFile( path.join(__dirname, './views/partials/', "weekly_graph.ejs"), {}, (err, data) => { if (err) { console.log(err); reject(err); // 出错时reject return; } console.log(data); resolve(data); // 成功时resolve数据 } ); }); }
这样修改后,async函数会返回这个Promise,await就能正确获取到resolve的HTML数据了。
内容的提问来源于stack exchange,提问作者Juliatzin
相关产品推荐
相关产品推荐

