a24*_*918 5 javascript promise async-await
我在 React 中有一个 dataService 函数来执行我的 API 获取。我尝试转换为 async/await 块,但似乎遇到了障碍。
使用承诺:
const dataService = (url, options, dataToPost) => {
return (dispatch, getState) => {
const { requestAction, successAction, failureAction } = options.actions;
if (options.shouldRequest(getState())) {
dispatch(requestAction());
const promise = axios.get(url, { withCredentials: true });
return promise
.then(response => {
if (response.status === 200) {
return dispatch(successAction(response, dispatch));
}
return Promise.reject(response);
})
.catch(error => {
if (error.response.status === 302) {
window.location = '/view';
}
dispatch(openErrorDialog());
return dispatch(failureAction(error));
});
}
return Promise.reject(new Error('FETCHING'));
};
};
Run Code Online (Sandbox Code Playgroud)
使用异步/等待:
const dataService = (url, options, dataToPost) => {
return (dispatch, getState) => {
const { requestAction, successAction, failureAction } = options.actions;
if (options.shouldRequest(getState())) {
dispatch(requestAction());
const promise = axios.get(url, { withCredentials: true });
return promise
.then(response => {
if (response.status === 200) {
return dispatch(successAction(response, dispatch));
}
return Promise.reject(response);
})
.catch(error => {
if (error.response.status === 302) {
window.location = '/view';
}
dispatch(openErrorDialog());
return dispatch(failureAction(error));
});
}
return Promise.reject(new Error('FETCHING'));
};
};
Run Code Online (Sandbox Code Playgroud)
错误是“操作必须是普通对象。对异步操作使用自定义中间件。”。承诺代码完美运行。我已经在使用 thunk。请指教。
如果你真的想改变 Promise -> async/await 那么改变如下:
首先,您不希望 dataService 成为async那样,这意味着它返回一个 Promise,这会改变它需要的调用方式 - 您不希望那样
其次,改变
const promise = axios.get ...
promise.then(response ....
Run Code Online (Sandbox Code Playgroud)
到
const promise = await axios.get ...
promise.then(response ....
Run Code Online (Sandbox Code Playgroud)
不会工作...
它需要是
const response = await axios.get ...
Run Code Online (Sandbox Code Playgroud)
不需要承诺变量
即便如此,您仍然在转换后的代码中使用 promises ......现在只是async无缘无故地使用关键字而有所不同
这是您的(原始)代码应如何转换为 async/await
请注意以下 Promise 一词的缺失:
const dataService = (url, options, dataToPost) => {
return async (dispatch, getState) => {
const { requestAction, successAction, failureAction } = options.actions;
if (options.shouldRequest(getState())) {
const data = typeof dataToPost === 'string' ? { data: dataToPost } : dataToPost;
dispatch(requestAction());
try {
const response = dataToPost
? await axios.post(url, data, { withCredentials: true })
: await axios.get(url, { withCredentials: true });
if (response.status === 200) {
return dispatch(successAction(response, dispatch));
}
throw response;
} catch(error) {
if (error.response.status === 302) {
window.location = '/view';
}
dispatch(openErrorDialog());
return dispatch(failureAction(error));
}
}
throw new Error('FETCHING');
};
};
Run Code Online (Sandbox Code Playgroud)
await axios.post(url, data, { withCredentials: true })不返回promise,它返回请求的真实响应。
使用 async-await 时不要使用 then-catch,而是使用 try-catch。这是修复方法
try {
const response = dataToPost
? await axios.post(url, data, { withCredentials: true })
: await axios.get(url, { withCredentials: true });
if (response.status === 200) {
return dispatch(successAction(response, dispatch));
}
return Promise.reject(response);
} catch (err) {
if (error.response.status === 302) {
window.location = '/view';
}
dispatch(openErrorDialog());
return dispatch(failureAction(error));
}
Run Code Online (Sandbox Code Playgroud)