为什么async/await函数返回pending状态Promise?已尝试.then仍无效
问题解答
核心错误原因
- 所有
async关键字声明的函数,返回值默认会被包装为Promise对象。你直接调用findData()没有做异步等待处理,拿到的自然是处于pending状态的Promise实例。你在函数内部await之后打印query能拿到正确值,是因为那行代码已经等待异步查询执行完成,但外部同步执行的代码不会等待异步函数内部的流程,所以直接获取返回值肯定是未完成的Promise。 - 你更新后写的匿名
async函数只做了声明,没有实际调用,函数内部的赋值代码从来没有执行过,自然不会生效。如果你之前尝试.then也无效,大概率是你把依赖research["uploaderInfo"]的逻辑写在了.then回调的外面,同步代码执行顺序早于异步回调,所以拿到的还是空值。
正确解决方案
方案1:用.then处理异步结果(无需额外async上下文)
const findData = async () => { let query = await userSchema.findOne({ _id: research["uploaderID"] }); return query; }; findData().then(query => { research["uploaderInfo"] = query; // 所有需要用到uploaderInfo的逻辑必须写在这个回调内部 console.log(research["uploaderInfo"]); })
方案2:立即执行匿名异步函数(IIFE写法)
给你定义的匿名异步函数末尾加()让它立即执行即可:
const findData = async () => { let query = await userSchema.findOne({ _id: research["uploaderID"] }); return query; }; // 末尾的()表示立即执行该函数 (async () => { research["uploaderInfo"] = await findData(); // 所有依赖uploaderInfo的逻辑都要写在这个函数内部、await之后 console.log(research["uploaderInfo"]); })();
方案3:顶层await(仅ES模块环境支持)
如果你的代码运行在ES Module环境(比如浏览器带type="module"的脚本、Node.js配置了ES模块规则),可以直接使用顶层await,不需要包裹函数:
const findData = async () => { let query = await userSchema.findOne({ _id: research["uploaderID"] }); return query; }; research["uploaderInfo"] = await findData(); console.log(research["uploaderInfo"]);
注意事项
任何需要用到research["uploaderInfo"]的逻辑,必须放在异步流程完成之后执行,也就是.then回调内部、或者await语句之后,不能放在异步代码的外部。
内容的提问来源于stack exchange,提问作者Walls
相关产品推荐
相关产品推荐

