我是javascript中Promises的普通用户。现在,我想尝试异步/等待。但由于对异步/等待的了解不足,我无法自拔。
我有一个使用Promise的功能,如下所示:
const asyncRequest = (funcA, b) => {
// do some syncronous stuff. e. g. console.log
console.log(b);
return funcA(b)
.then((something) => console.log(something))
.catch((err) => console.log(err))
}
我试图将上述基于Promise的代码转换为async / await:
const asyncRequest = async (funcA, b) => {
// do some syncronous stuff. e. g. console.log
console.log(b);
try {
const something = await funcA(b);
console.log(something);
} catch (err) {
console.log(err);
}
}
函数转换看起来很容易。但是我注意到在基于Promise的代码中有return
关键字。但是在我的异步/等待代码中,我很困惑。我应该退还什么?
真实示例:
基于承诺的示例
const Toast = {};
const createAsyncAction = ({
asyncRequest, types, loadingPayload = null, showToastOnError = true,
}) => (dispatch) => {
dispatch({
type: types.loading,
payload: loadingPayload,
});
return asyncRequest()
.then((response) => {
if (response.isMock) { // if mock request
dispatch({
type: types.success,
payload: response.payload,
});
return;
}
if ([2, 3].includes(String(response.status).substring(0, 1))) { // if request succeeds
response.json()
.then((res) => {
if (res.statusCode === 1000) {
dispatch({
type: types.success,
payload: res.data,
});
return;
}
dispatch({ // if its a known error by server
type: types.failure,
payload: {
code: res.statusCode,
message: res.message,
},
});
if (showToastOnError) {
Toast.error(`${res.statusCode}: ${res.message}`);
}
}).catch((error) => { // if response is not convertible to json
dispatch({
type: types.failure,
payload: {
code: response.status,
message: error.message,
},
});
if (showToastOnError) {
Toast.error(`${response.status}: ${error.message}`);
}
});
return;
}
dispatch((error) => { // if request fails with some status codes like 404, 500...
dispatch({
type: types.failure,
payload: {
code: response.status,
message: error.message,
},
});
if (showToastOnError) {
Toast.error(`${response.status}: ${error.message}`);
}
});
}).catch(() => { // if request cannot be made due to some internet or connection issue
dispatch({
type: types.failure,
payload: {
code: 0,
message: 'Connection issue. Make sure your are connected to the internet and that your API is working',
},
});
if (showToastOnError) {
Toast.error('Connection issue. Make sure your are connected to the internet and that your API is working');
}
});
};
export default createAsyncAction;
异步/等待示例:
const Toast = {};
const createAsyncAction = ({
asyncRequest, types, loadingPayload = null, showToastOnError = true,
}) => async (dispatch) => {
dispatch({
type: types.loading,
payload: loadingPayload,
});
try {
const response = await asyncRequest();
if (response.isMock) { // if mock request
dispatch({
type: types.success,
payload: response.payload,
});
return;
}
if ([2, 3].includes(String(response.status).substring(0, 1))) { // if request succeeds
try {
const jsonResponse = await response.json();
if (jsonResponse.statusCode === 1000) {
dispatch({
type: types.success,
payload: jsonResponse.data,
});
return;
}
dispatch({ // if its a known error by server
type: types.failure,
payload: {
code: jsonResponse.statusCode,
message: jsonResponse.message,
},
});
if (showToastOnError) {
Toast.error(`${jsonResponse.statusCode}: ${jsonResponse.message}`);
}
} catch (error) {
dispatch({
type: types.failure,
payload: {
code: response.status,
message: error.message,
},
});
if (showToastOnError) {
Toast.error(`${response.status}: ${error.message}`);
}
}
return;
}
dispatch((error) => { // if request fails with some status codes like 404, 500...
dispatch({
type: types.failure,
payload: {
code: response.status,
message: error.message,
},
});
if (showToastOnError) {
Toast.error(`${response.status}: ${error.message}`);
}
});
} catch (_) {
dispatch({
type: types.failure,
payload: {
code: 0,
message: 'Connection issue. Make sure your are connected to the internet and that your API is working',
},
});
if (showToastOnError) {
Toast.error('Connection issue. Make sure your are connected to the internet and that your API is working');
}
}
};
export default createAsyncAction;
答案 0 :(得分:1)
您不需要一个!
任何标记为async
的函数都将始终返回承诺。现在,如果您希望该承诺解决某件事,那么您将需要返回一个值。但是,由于您只是在做console.log
,它的返回值是undefined
,所以就等于什么都不返回(因为如果没有指定的返回值,JavaScript会隐式返回undefined
)。
来自async
docs:
异步函数是异步运行的函数 通过事件循环,使用隐式
Promise
返回其结果。
因此,async
将隐式地从包装在Promise
中的函数返回任何返回值。
答案 1 :(得分:0)
您不需要退货。那不是造成代码差异的原因。在您的示例中,您需要在调用funcA(b)时使用await
,因为您希望让js在解析的同时做其他事情。
const asyncRequest = async (funcA, b) => {
// do some syncronous stuff. e. g. console.log
console.log(b);
try {
const something = await funcA(b);
console.log(something);
} catch (err) {
console.log(err);
}
}
答案 2 :(得分:-1)
两个函数都返回Promises。
在第一种情况下,这是因为您要返回Promise链。在第二种情况下,这是因为根据定义,所有async
函数都返回Promises。因此,“返回承诺”消息在第二个函数中是隐含的。
当您从async
函数返回一个值时,该值即为承诺的解析值。如果您未返回任何内容,则将使用值undefined
来解决承诺。在这种情况下,实际上是在函数.then((something) => console.log(something))
中返回的值。当然,这是undefined
,因此您无需返回任何内容。