将 Promise 转换为 async/await - Javascript

Posted

技术标签:

【中文标题】将 Promise 转换为 async/await - Javascript【英文标题】:Converting promises to async/await - Javascript 【发布时间】:2019-08-11 20:26:23 【问题描述】:

我在 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'));
    ;
;

使用异步/等待:

	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了。请指教。

【问题讨论】:

你所做的一切毫无意义,因为 const promise = dataToPost ? .... 不会是一个承诺 - 让我们面对现实吧,你所做的只是将 dataService 标记为异步,所以现在它不返回其中声明的函数,它返回该函数的承诺 尝试将 async 关键字从 dataService 中删除到 dataService = (url, options, dataToPost) 这可能会有所帮助:***.com/questions/50059724/… 【参考方案1】:

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

【讨论】:

@Ben:???每个async 函数都返回一个Promise 对象。 await 语句在Promise 上运行,等待Promise 解决或拒绝。所以@Gianfranco Fertino 是正确的。【参考方案2】:

如果你真的想更改 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 ...

不需要承诺变量

即便如此,您在转换后的代码中仍在使用 Promise ... 现在的不同之处在于无缘无故地使用了 async 关键字

您的(原始)代码应如何转换为 async/await

请注意以下单词 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');
    ;
;

【讨论】:

以上是关于将 Promise 转换为 async/await - Javascript的主要内容,如果未能解决你的问题,请参考以下文章

如何将 onload 承诺转换为 Async/Await

promise和async/await

promise和async/await

promise和async/await

promise和async/await

js异步回调Async/Await与Promise区别 新学习使用Async/Await