异步等待和承诺链不等待解决

async await and promise chain is not waiting to resolve

我将我的 API 调用放在一个新函数中,这样我就可以轻松地用几行代码调用它们,而不是在每个页面上使用大量代码。我遇到的问题是异步和等待在 returning 数据之前完成。

我首先得到 console.log(sess.getIdToken().getJwtToken()) 的安慰,然后是 console.log(getMessages) 的未定义,然后是来自 [=17 的数据=](响应)。

所以 await Auth.currentSession().then(...) 运行但不等待其中的 axios 调用。如何 return 数据以便我可以在 useEffect 中访问它?

useEffect(() => {
    async function getMessages() {
        const getMessages = await ApiService.getMessages();
        console.log(getMessages)
    }
    getMessages();
}, []);

async getMessages() {
    return await this.__sendRequest("/default/message", "GET");
}

async __sendRequest(url, method) {
    await Auth.currentSession().then(sess => {
        console.log(sess.getIdToken().getJwtToken())
        axios({
            method: method,
            url: process.env.REACT_APP_USER_URL + url,
            headers: {
                "X-TOKEN-ID": sess.getIdToken().getJwtToken(),
                "addresseeType": "P",
                "content-type": "application/json"
            }
        }).then(function (response) {
            console.log(response)
            return response
        }).catch(err => {
            console.error(err);
        })
    })
}

async/await 与承诺链 (.then(...)) 混合使用是使代码过于复杂的一种非常简单的方法。

我看到有几个地方导致此问题不起作用。

  • __sendRequest 你没有 returning 任何东西。
  • 在第一个 .then 中你也缺少一个 return。

这里是一个简化和固定的代码

async __sendRequest(url, method) {
    const sess = await Auth.currentSession()

    console.log(sess.getIdToken().getJwtToken())
    
    const response = await axios({
        method: method,
        url: process.env.REACT_APP_USER_URL + url,
        headers: {
            "X-TOKEN-ID": sess.getIdToken().getJwtToken(),
            "addresseeType": "P",
            "content-type": "application/json"
        }
    })

    console.log(response)

    return response
}

查看其他答案的评论,了解 async/await、returning 和调用堆栈

有几个问题:

  1. __sendRequest 没有 return,所以当它完成等待后,它会用 undefined.
  2. 履行它的承诺
  3. 来自 Auth.currentSession() 链的承诺不会完全等待 axios 调用,因为这两个链没有以任何方式链接。
  4. (这不是您看到过早解决的原因,但仍然是一个问题。)不要过早地捕获错误,让它们传播,以便调用者知道出现了问题。

另外,一般情况下,不要混用.then/.catchasync/await,没必要(一般);只需使用 await:

useEffect(() => {
    async function getMessages() {
        try {
            const getMessages = await ApiService.getMessages();
            console.log(getMessages);
        } catch (error) {
            // ...*** handle/report error...
        }
    }
    getMessages();
}, []);

async getMessages() {
    return await this.__sendRequest("/default/message", "GET");
}

async __sendRequest(url, method) {
    const sess = await Auth.currentSession();
    console.log(sess.getIdToken().getJwtToken());
    return await axios({
        method: method,
        url: process.env.REACT_APP_USER_URL + url,
        headers: {
            "X-TOKEN-ID": sess.getIdToken().getJwtToken(),
            "addresseeType": "P",
            "content-type": "application/json"
        }
    });
}

getMessages() 是异步的,所以你需要调用 await 并使第一行异步的回调函数,以便您可以在其中使用等待。

  useEffect(async () => {
    async function getMessages() {
        const getMessages = await ApiService.getMessages();
        console.log(getMessages)
    }
    await getMessages();
 }, []);

您可以通过将所有 then() 回调转换为 await 并将整个链放入 try/catch 块中来简化 __sendRequest。