Node.js中async/await调用fs.readFile顺序错乱及oauth2Client凭证不更新问题
核心问题原因
await 只能等待 Promise 对象的执行结果,你当前使用的回调形式的 fs.readFile 不会返回 Promise,所以 await 语句不会等待文件读取和回调逻辑执行完成,就会继续往下执行后续代码,才会出现先打印HI、后打印hello的情况,调用谷歌接口时凭证还没完成赋值。同时后续调用 google drive 接口时也混用了 await 和回调,也会导致逻辑顺序不符合预期。
修复方案
- 改用 Promise 版本的文件读取方法,Node.js 内置的
fs.promises模块已经提供了 promisify 后的文件操作接口,不需要传入回调,读取结果直接通过 await 拿到 - 谷歌官方 Node.js SDK 调用同时支持回调和 Promise 两种写法,选择 Promise 写法配合 await 即可保证执行顺序
修改后的代码如下:
const getFile = async (req, res, next) => { try { // 等待文件读取完成再往下执行 const token = await fs.promises.readFile(TOKEN_PATH); console.log("hello") const parsedToken = JSON.parse(token); console.log(parsedToken); oauth2Client.credentials = parsedToken; console.log("HI") const service = google.drive({ version: 'v3', encoding: null }); console.log(oauth2Client); // 等待接口请求完成再处理结果 const response = await service.files.get({ auth: oauth2Client, fileId: "1ZR8kkvb2JYVxcUjmlgfBJD2IYnisaiFn", alt: 'media' }); responder(res)(null,response); } catch (err) { // 统一捕获所有异步错误,包含文件读取错误、接口调用错误 console.log('执行出错: ' + err); // 可根据业务需要补充错误响应逻辑,或者调用next(err)交给上层处理 } }
如果你的 Node.js 版本不支持 fs.promises,可以用 util 模块的 promisify 方法转换回调式API:
const { promisify } = require('util'); const readFile = promisify(fs.readFile); // 后续直接await readFile(TOKEN_PATH)即可,逻辑和上面一致
修改后代码会先执行文件读取逻辑打印hello,再执行后续逻辑打印HI,凭证会在接口调用前完成赋值,执行顺序完全符合预期。
内容的提问来源于stack exchange,提问作者Shashank motruri
相关产品推荐
相关产品推荐

