[英]difference using async vs return new Promise
我试图从 NextJS API 页面调用异步实用程序 function,但未定义。 当我 go 到 localhost:300/api/hello 时控制台打印如下
result = undefined
文件一: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 function 更改为以下工作,但我不明白为什么。 异步不也返回 promise 吗? 如果非要写在async/await方法中,我应该怎么写go呢?
文件 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;
});
})
}
在getCountries
的第一个示例中,您返回的是 promise 的空值(未定义),而在第二个示例中,您返回的是 promise 的响应。
在您的第一个示例中发生的情况是axios.get
运行,但是没有什么能真正阻止 function 返回。 在axios.get
上调用.then
的全部目的是为了在 promise 解决后执行.then
回调中的任何内容。 否则,您可以像往常一样在axios.get
调用.then
之后编写您正在编写的代码,如果您使用 await,您可以这样做。 使用await
会停止代码执行,直到 promise 被解决或拒绝(这就是为什么你应该只在 try-catch 块中使用await
。
如果你的第一个例子重构如下:
const getCountries = async () => {
const params = { action: "get_countries", ...authKey }
try {
const result = await axios.get(APIFOOTBALL_URL, { params: params });
const response = [...result.data];
return response;
} catch (err) {
console.error("An error occurred while trying to fetch countries: ", err);
throw err;
}
}
您最终会在axios.get
调用之后阻止代码的执行,直到 promise 被解决或拒绝。
简而言之,您的第一个示例不起作用的原因是因为您的 function 在axios.get
调用之后返回undefined
(隐含地因为您的第一个示例中没有 return 语句)。 没有什么能阻止它返回,因此您的第一个示例返回的 promise 总是用undefined
的值解析。
您的第二个示例之所以有效,是因为当您手动返回 promise 时,它始终处于待处理状态,直到您使用resolve(response);
或reject
。
如果这没有帮助,请这样考虑 -> 在调用代码中,当您执行getCountries.then
时, .then
部分仅在解析 promise 时执行。 它解析的值被传递给回调(您用作result
)。 在您的第一个示例中, getCountries
立即解析为undefined
的值,因此您的回调获取undefined
的值,而在第二个示例中, getCountries
返回的 promise 待处理,直到在您的代码中调用resolve
,这仅在您的 API 请求之后发生promise 解析(因为您在axios.get
.then
中调用它)。
另外,在您的第一个示例中,当您return response;
在axios.get
.then
,您从 .then 的回调.then
返回。 这不会从getCountries
function 返回。也许这让您认为这应该有效,但实际上无效。
如果你这样做,你的第一个例子也可以工作:
const getCountries = async () => {
const params = { action: "get_countries", ...authKey }
return axios.get(APIFOOTBALL_URL, { params: params })
.then((result) => {
const response = [...result.data];
return response;
}).catch((err) => {
throw err;
});
}
因为现在, getCountries
正在返回一个 promise 的响应,而不是仅仅返回一个 promise 的undefined
。
最后,正如@jfriend00 提到的,没有理由让.catch()
再次抛出错误。 catch 的目的是处理错误(记录或处理错误)。 您现在使用.catch()
的方式将具有与根本不使用它相同的行为。
在async
function 中,您必须await
您的 promise 或必须返回它。 如果没有其中之一,实际上没有什么会等待 promise 或从中返回任何结果。 由于使用async
的目的是为了能够使用await
,下面是它的样子:
const getCountries = async () => {
const params = { action: "get_countries", ...authKey }
const result = await axios.get(APIFOOTBALL_URL, { params: params });
return result.data;
}
或者,您可以只返回 promise 而不需要async
:
const getCountries = () => {
const params = { action: "get_countries", ...authKey }
return axios.get(APIFOOTBALL_URL, { params: params }).then(result =>{
return result.data;
});
}
关于您的代码的其他一些注意事项:
var
了。 在所有现代 Javascript 中使用let
或const
代替。response = [...result.data];
. 你可以做return result.data
。axios.get()
调用返回的那个)。这只是没有必要,而且经常会产生错误处理问题,而你确实有错误处理,因为你没有调用reject(err)
正确。.catch()
只throw err
,除非您在该.catch()
中还有一些其他代码(例如记录错误)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.