简体   繁体   English

将promises转换为async / await - Javascript

[英]Converting promises to async/await - Javascript

I have a dataService function in React that does my API fetching. 我在React中有一个dataService函数来执行我的API获取。 I tried converting to async/await block but seem to hit a roadblock. 我尝试转换为async / await块,但似乎遇到了障碍。

Using promises: 使用承诺:

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'));
    };
};

Using async/await: 使用async / await:

  const dataService = async (url, options, dataToPost) => { return async (dispatch, getState) => { let url; const {requestAction, successAction, failureAction} = options.actions; if (options.shouldRequest(getState())) { dispatch(requestAction()); const promise = axios.get(url, {withCredentials: true}); try { const response = await promise; if (response.status === 200) { return dispatch(successAction(response, dispatch)); } return Promise.reject(response); } catch (error) { return dispatch(failureAction(error)); } } return Promise.reject(new Error('FETCHING')); }; }; 

The error is "Actions must be plain objects. Use custom middleware for async actions.". 错误是“操作必须是普通对象。使用自定义中间件进行异步操作。”。 The promises code works perfecty. 承诺代码完美无缺。 I am already using thunk. 我已经在使用thunk了。 Please advice. 请指教。

await axios.post(url, data, { withCredentials: true }) does not return promise, it returns the real response of the request. await axios.post(url, data, { withCredentials: true })不返回promise,它返回请求的真实响应。

do not use then-catch when using async-await, use try-catch instead. 使用async-await时不要使用then-catch,而是使用try-catch。 here is the fix 这是修复

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));
}

If you truly want to change Promise -> async/await then the changes are as follows: 如果你真的想要改变Promise - > async / await,那么更改如下:

For a start, you DONT want dataService to be async as that will mean it returns a Promise, which changes how it needs to be called - you dont' wnat that 首先,你不希望dataService async因为它意味着它返回一个Promise,它改变了它需要被调用的方式 - 你不会那么想

Secondly, changing 其次,改变

  const promise = axios.get ...
  promise.then(response ....

to

  const promise = await axios.get ...
  promise.then(response ....

wont work ... 不会工作......

it needs to be 它需要

const response = await axios.get ...

no need for the promise variable 不需要promise变量

Even so, you're still using promises in your converted code ... which now is only different by having async keywords for no reason 即便如此,你仍然在你转换的代码中使用promises ...现在只有不同的async关键字才有所不同

Here's how your (original) code should be converted to async/await 以下是您的(原始)代码应转换为异步/等待的方式

note the total LACK of the word Promise in what follows: 请注意以下内容中Promise一词的总LACK:

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');
    };
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM