首页 > 解决方案 > 如何在 javascript 中避免 .then() 地狱?

问题描述

我很难对 API 调用进行排序。所以我使用 then() 链接按顺序排列它们。所有 API 和刷新令牌都是 Promises/Async。它正在工作,但是否有更清洁/更漂亮/更短的方法而不使用异步/等待,因为我的父函数不是异步的。我不完全理解 .then() 和 async/await 的行为

这是父函数内部的代码:

 refreshToken().then(token => {
                let request = {} //format request

                return axios.post(`${youtubeUrl}/upload/youtube/v3/videos?access_token=${token}&part=contentDetails`, request) //upload video
            })
            .then(uploadResponse => {
                let uploadResponse = {}; //format uploadResponse

                refreshToken().then(token => { //refresh the token again
                    return axios.put(`${youtubeUrl}?access_token=${token}`, uploadResponse) //update existing video
                })
                .then(updateResponse => {
                    let updateResponse = {}; //format updateResponse

                    axios.post(`${BasePath}/v1/videos`, updateResponse, headers)
                    .then(postResponse => {
                        if (postResponse.data.response === 'success') {
                            return dispatch(receivePostsData(postResponse.data))
                        } else if (postResponse.data.response === 'failed') return dispatch(receivePostsData(postResponse.data))
                    })
                })
            })    
            .catch(error => {
                return dispatch(receivePostsData(error))
            })

标签: javascriptnode.jsreactjsecmascript-6

解决方案


使用 aysnc await 您可以将回调地狱转换为:

重要说明是:

  • 函数允许使用 await 之前的 async 关键字
  • 要处理异常,您需要使用 try catch 块。
async function uploadToYoutube() {

    try {
        let token = await refreshToken();

        let request = {}

        const youtubeUploadResponse = await axios.post(`${youtubeUrl}/upload/youtube/v3/videos?access_token=${token}&part=contentDetails`, request);

        let uploadResponse = {};

        token = await refreshToken();

        const youtubeUpdateResponse = await axios.put(`${youtubeUrl}?access_token=${token}`, uploadResponse);

        let updateResponse = {};

        let postResponse = await axios.post(`${BasePath}/v1/videos`, updateResponse, headers);

        if (postResponse.data.response === 'success') {
            return dispatch(receivePostsData(postResponse.data))
        } else if (postResponse.data.response === 'failed') {
            //??? why do you here act like a success?
            return dispatch(receivePostsData(postResponse.data))
        }
    } catch (error) {
        //??? why do you here act like a success?
        return dispatch(receivePostsData(error))
    }
}

推荐阅读