[英]How to construct a Promise that calls an async function inside of it, parses the result, and then resolves/rejects?
我想编写一个函数getUser()
,它返回一个 Promise ,它在resolve
时传递用户对象,在reject
时传递错误。 我正在使用 axios 提出请求。
这是我目前拥有的。
async function getUser() {
try {
const userResponse = await axios({
method: 'post',
url: "some_url",
data: "some string data",
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
});
if (userResponse.data.status === 'success') {
// resolve(validateResponse.data);
} else {
// reject(validateResponse.data);
}
} catch (error) {
// reject(validateResponse.data);
}
}
我想将整个try...catch
块包装在Promise
构造函数中,但 Promise 构造函数是new Promise((resolve, reject) => {...})
而不是new Promise(async (resolve, reject) => {...})
。 我知道我可以做后者,但这是一种反模式。
Promise
方法也不一定有效,因为当我使用getUser()
和.catch()
返回的Promise
时出现任何错误,我不知道错误是否来自服务器的响应(状态不是'success'
) 或者如果请求本身失败。
解决这个问题的最安全方法是什么? 我知道有一个蛮力的解决方案,就是在不实际使用的情况下模仿Promise
API,或者声明一个async
Promise,但我觉得我每次都遇到了反模式。
感谢您的任何建议。
我将从概念上回答这个问题。
当您调用异步函数时,它会立即向调用该函数的代码范围返回一个承诺。
在异步函数内部,您不需要使用resolve
和reject
。 相反,您可以只使用return
和throw
。 你return
就是承诺将解决的问题。 如果您throw
,这就是承诺将“拒绝”的内容。 尝试这样的事情:
async function getUser() {
try {
const userResponse = await axios({
method: 'post',
url: "some_url",
data: "some string data",
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
});
if (userResponse.data.status === 'success') {
return validateResponse.data;
} else {
throw new Error(validateResponse.data);
}
} catch (error) {
throw error;
}
}
在 async/await 出现后,我在处理 promise 时不再喜欢then
语法。 为避免then
,请从异步函数的主体中调用getUser
。 如果您不是从异步函数的主体中调用getUser
,您将无法await
它解析为的内容; 你将不得不使用then
代替。 或者,您可以将该调用代码包装在立即调用的异步函数中,以便您确实可以使用await
。 这是我的代码(调用getUser
)的粗略示例:
(async function()
{
let user = await getUser();
if(!user)
{
console.error(`Access Denied`);
return;
}
// Rest of your code that should only run when you have a user goes here.
})();
我将上面的代码包装在一个立即调用的异步函数中的唯一原因是,我可以使用await
而不是then
来解决该承诺。
标有async
函数旨在使用 promise .then()
回调样式编写。 也就是说,为了解析一个值,你使用return
关键字,为了拒绝一个值,你使用throw
关键字。 因此,您的函数应编写如下:
async function getUser() {
try {
const userResponse = await axios({
method: 'post',
url: "some_url",
data: "some string data",
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
});
if (userResponse.data.status === 'success') {
return validateResponse.data;
} else {
throw new Error(validateResponse.data);
// Alternately you can also just:
// throw validateResponse.data
}
} catch (error) {
throw new Error(validateResponse.data);
}
}
Promise 方法也不一定有效,因为当我使用 getUser() 和 .catch() 返回的 Promise 时出现任何错误,我不知道错误是否来自服务器的响应(状态不是 'success ') 或者如果请求本身失败。
我会考虑以两种可检查的方式之一拒绝getUser
内部的外部承诺 - 然后使用承诺拓扑调用getUser
,该拓扑将好的数据拆分为处理流(承诺链),并将错误拆分为另一个以进行区分。 例如:
创建一个名为 GetUserData 的数据包装器构造函数:
const GetUserData = function( data) { this.data = data; }
这可能会受益于为getUser
参数值设置另一个参数。
删除try {
和catch() {}
子句。 让 axios 错误抛出并拒绝getUser
承诺。
让getUser
返回“成功”的结果或抛出一个GetUserData
对象:
if (userResponse.data.status === 'success') { return userResponse.data; } else { throw new GetUser( userResponse.data); }
使用区分错误类型的拓扑调用getUser
:
let userPromise = getUser(); // parameterized? userPromise.then(data => { do something with user data}); // chain promises on "success" as needed // split errors into a .then handler for server errors and a .catch handler for axios errors: userPromise.catch( something => { if( something instanceOf GetUserData) { return something.data; } throw something; // rethrow axios error }) .then ( data => { deal with unsuccessful server data}) .catch( error => { deal with axios error })
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.