readFile无Promise返回时,如何让NestJS控制器等待函数执行?
解决方案
要让控制器等待异步文件读取操作完成,核心是把基于回调的readFile转换为Promise形式,这样就能使用async/await语法。下面提供两种可行的实现方式:
方式一:手动将readFile包装为Promise
修改仓库类的findOne方法,把回调逻辑包裹在Promise中,手动处理成功和失败的情况:
findOne(id: number): Promise<any> { return new Promise((resolve, reject) => { readFile('messages.json', 'utf8', (err, file: string) => { // 处理文件读取错误 if (err) { reject(err); return; } try { const messages = JSON.parse(file); resolve(messages[id]); } catch (parseErr) { // 处理JSON解析错误 reject(parseErr); } }); }); }
方式二:使用Node.js内置的Promise版fs API
Node.js的fs模块提供了promises子模块,其中的readFile本身就返回Promise,无需手动包装,代码更简洁:
首先导入Promise版的readFile:
import { readFile } from 'fs/promises';
然后修改仓库类的findOne方法:
async findOne(id: number) { try { const file = await readFile('messages.json', 'utf8'); const messages = JSON.parse(file); return messages[id]; } catch (err) { // 统一处理文件读取或JSON解析错误 throw err; } }
同步修改服务层与控制器
不管用哪种方式,仓库层的findOne现在都返回Promise,所以服务层和控制器需要改成异步形式:
服务层代码修改
async findOne(id: number) { return this.messagesRepo.findOne(id); }
控制器代码修改
在方法前添加async关键字,并用await等待服务层的调用结果:
@Get('/:id') async getMessage(@Param() param: GetMessageDTO) { const message = await this.messagesService.findOne(param.id); if (message == null) { throw new NotFoundException('message not found'); } return message; }
补充说明
- 建议在仓库层或服务层捕获并处理文件读取、JSON解析的错误,避免错误直接抛到控制器层;
- 如果你的项目中使用了NestJS等框架,框架会自动处理Promise返回值,无需额外转换。
内容的提问来源于stack exchange,提问作者esraa
相关产品推荐
相关产品推荐

