Преобразование обещаний в асинхронное / ожидание - Javascript - PullRequest
3 голосов
/ 21 марта 2019

У меня есть функция dataService в React, которая выполняет выборку 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'));
    };
};

Использование 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'));
	    };
	};

Ошибка: «Действия должны быть простыми объектами. Используйте пользовательское промежуточное ПО для асинхронных действий».Код обещаний работает отлично.Я уже использую Thunk.Пожалуйста, совет.

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Если вы действительно хотите изменить Promise -> async / await, тогда изменения будут следующими:

Для начала, вам НЕ нужно, чтобы dataService был async, поскольку это будет означать, что он возвращает Promise,который меняет то, как он должен быть вызван - вы не хотите, чтобы

Во-вторых, изменение

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

на

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

не будет работать ...

это должно быть

const response = await axios.get ...

нет необходимости в переменной обещания

Несмотря на это, вы все еще используете обещания в преобразованном коде ...который теперь отличается только наличием 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');
    };
};
1 голос
/ 21 марта 2019

await axios.post(url, data, { withCredentials: true }) не возвращает обещание, оно возвращает реальный ответ на запрос.

не используйте then-catch при использовании async-await, вместо этого используйте 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));
}
...