如何让含Promise的async函数返回解析后的值而非Pending Promise?
问题描述
用户编写了异步函数run(),通过axios获取赛事数据后计算指定球队的总进球数。函数内部的console.log能正确输出进球数,但直接调用run()时,返回的始终是pending状态的Promise。用户知道可以通过.then()链式调用获取结果,但希望能直接拿到可使用的goals值,无需依赖.then(),此前尝试用另一个async函数调用run()但未成功。
对应的代码如下:
async function run(teamKey) { let { data } = await axios.get(URL); const { rounds } = data; let goals = 0; rounds.forEach((matchday) => { matchday.matches.forEach((match) => { if (match.team1.key == teamKey) { goals += match.score1; } else if (match.team2.key == teamKey) { goals += match.score2; } }); }); console.log("goals: ", goals); // 控制台能看到正确的进球数 return goals; // 但返回的是pending状态的Promise } console.log("run(): ", run("arsenal"));
解决方案
首先明确:async函数的返回值必然是Promise,这是JavaScript的语法规则,没法让它直接返回原始的数值类型。但可以通过以下方式实现“不用显式写.then()”的效果:
1. 在async函数内部用await调用
你之前的思路是对的,大概率是调用方式有误。正确写法如下:
// 包裹一个async函数 async function getTeamGoals() { // 用await等待run()的Promise resolve,拿到实际的goals值 const goals = await run("arsenal"); console.log("球队总进球数:", goals); // 这里可以直接用goals做任何后续操作,比如渲染到页面、计算其他数据等 } // 调用这个函数 getTeamGoals();
注意:await关键字只能在async标记的函数内部使用,不能直接写在全局作用域(除非你的代码运行在支持顶级await的环境中)。
2. 直接使用顶级await(仅限支持的环境)
如果你的代码是在支持顶级await的环境里(比如现代浏览器的ES模块、Node.js 14.8及以上版本的ES模块),可以不用额外包裹函数,直接在全局作用域用await:
// 前提:代码是ES模块(浏览器中通过type="module"引入,Node.js中用.mjs后缀或设置"type": "module") const goals = await run("arsenal"); console.log("run(): ", goals);
3. 别忘了错误处理
不管用哪种方式,都建议加上错误处理逻辑,避免axios请求失败(比如网络问题、接口报错)导致程序崩溃:
async function getTeamGoals() { try { const goals = await run("arsenal"); console.log("球队总进球数:", goals); } catch (error) { // 捕获请求或计算过程中出现的错误 console.error("获取数据失败:", error); } } getTeamGoals();
内容的提问来源于stack exchange,提问作者dmp990
相关产品推荐
相关产品推荐

