NextJS API调用async工具函数返回undefined问题及async与Promise差异
问题:NextJS API调用async工具函数返回undefined
我在NextJS的API页面调用一个async工具函数时,返回了undefined。访问localhost:300/api/hello时,控制台输出:
result = undefined
相关代码
文件1:api/hello.js
export default function handler(req, res) { getCountries().then(result=>{ console.log('result = ', result); res.status(200).json({ status: 'ok', data: result.data }); }).catch(err=>{ console.log('error = ', err); res.status(500).json({ status: 'error', error: err }); }) }
文件2:utils/getCountries.js(无效版本)
const getCountries = async () => { var response = []; var params = { action: "get_countries", ...authKey } axios.get(APIFOOTBALL_URL, { params: params }) .then((result) => { response = [...result.data]; return response; }).catch((err) => { throw err; }); } export default getCountries;
将getCountries函数修改为以下版本后可以正常运行,但我不理解原因:async函数不也会返回Promise吗?如果必须用async/await方式编写,应该如何实现?
文件2:utils/getCountries.js(有效版本)
const getCountries = () => { return new Promise((resolve, reject) =>{ var response = []; var params = { action: "get_countries", ...authKey } axios.get(APIFOOTBALL_URL, { params: params }) .then((result) => { response = [...result.data]; resolve(response); }).catch((err) => { reject; }); }) }
解答
为什么无效版本会返回undefined?
虽然你给函数加了async关键字,但函数内部没有返回任何值,也没有等待异步操作完成。async函数确实会自动返回Promise,但如果函数体里没有显式return,它会返回一个状态为resolved且值为undefined的Promise。
你在无效版本里调用axios.get()后,只是注册了.then()回调,但回调里的return response只是回调函数的返回值,和外层的getCountries函数无关。外层函数根本没返回任何东西,所以最终拿到的结果就是undefined。
正确的async/await写法
直接用await等待axios请求完成,然后返回处理后的数据即可:
// 确保已导入axios、定义APIFOOTBALL_URL和authKey import axios from 'axios'; const getCountries = async () => { const params = { action: "get_countries", ...authKey }; // 等待axios请求完成,拿到结果 const result = await axios.get(APIFOOTBALL_URL, { params }); // 返回处理后的数据,async函数会自动包装为Promise return [...result.data]; }; export default getCountries;
关键说明:
await会暂停函数执行,直到axios.get()的Promise完成,直接拿到响应结果- 显式返回处理后的数据,
async函数会自动把这个值包装成resolved状态的Promise - 如果请求出错,错误会自动被
async函数包装成rejected状态的Promise,外层API handler的.catch()可以正常捕获
如果你一定要保留.then()写法(不推荐),需要记得返回axios的Promise:
const getCountries = async () => { const params = { action: "get_countries", ...authKey }; // 必须返回这个Promise链 return axios.get(APIFOOTBALL_URL, { params }) .then((result) => { return [...result.data]; }); };
但这种写法违背了async/await简化异步代码的初衷,推荐使用纯async/await的写法。
内容的提问来源于stack exchange,提问作者holangun
相关产品推荐
相关产品推荐

