开发者问题收集

在 React 应用程序中连续调用两个异步函数

2022-03-14
1227

我有两个 async 函数可以连接到 API 端点(无服务器框架) - 一个获取并返回令牌,另一个使用令牌获取并返回数据。

我使用简单的按钮测试这些函数,其中 onClick 分别调用函数来提取令牌和数据。单击一个按钮获取令牌,该令牌将保存到状态。然后,一旦我看到已收到令牌,我就会单击另一个按钮来获取数据。这完全没有任何问题。

问题是当我尝试从 React 应用程序按顺序调用它们时。当用户提交请求时,我需要连续调用它们。我似乎无法让代码等待令牌到达后再尝试提取数据。

按钮的 onClick 方法中调用的函数:

const tokenBtnOnClick = () =>
{
  const response = getToken().then(x => {
    setToken(x.data.response.token)
  })
}

const dataBtnOnClick = () =>
{
  const response = getData(token, param1, param2, param3).then(x => {
    setData(x.data.response)
  })
}

Async 函数:

export async function getToken()
{
    const apiUrl = `${BASE_URL}/handler/getToken`
    const axios = require('axios').default

    let response
    try
    {
        response = await axios.get(apiUrl)
    }
    catch (e)
    {
        console.log(e)
    }

    if (response)
    {
        return response
    }
    else
    {
        return ''
    }
}

export async function getData(token, param1, param2, param3)
{
    const apiUrl = `${BASE_URL}/handler/getData?token=${token}&param1=${param1}&param2=${param2}&param3=${param3}`
    const axios = require('axios').default

    let response
    try
    {
        response = await axios.post(apiUrl)
    }
    catch (e)
    {
        console.log(e)
    }

    if (response)
    {
        return response
    }
    else
    {
        return ''
    }
}

我尝试在单个按钮的 onClick 中调用此 getBoth() 函数:

async function getBoth()
{
  const tokenResponse = await tokenBtnOnClick().then(x => setToken(x.data.response.token))
  const dataResponse = await dataBtnOnClick().then(x => setData(x.data.response))
}

但即使它是一个在两行上使用 awaitasync 函数,我总是得到相同的 TypeError ,因为 dataBtnOnClick 被立即调用,而没有真正等待令牌进入。当我运行此代码时,调用 tokenBtnOnClick ,应用程序由于 TypeError ,然后令牌进入并被记录并保存到状态。

我也尝试过这个:(其中 getData 与上面完全相同,但现在接受 token 作为参数而不是使用状态变量)

async function getBoth()
{
  const response = await getToken().then(x => getData(x.data.response.token))
}

index.js?bee7:59 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'then')

我如何让它真正等待令牌进入后再尝试提取数据?

2个回答

您正在调用 setToken ,并且期望 token 立即更新,但是 setToken 将异步应用。

您可以使用 useEffect 解决您的问题吗?

useEffect(() => {
  getData(token, param1, param2, param3).then(x => {
    setData(x.data.response)
  })
}, [token])
twharmon
2022-03-14

尝试这个

const tokenBtnOnClick = () =>{
       setToken(getToken())
    }

    const dataBtnOnClick = () =>{
       setData(getData(token, param1, param2, param3))
    }

const axios = require('axios').default

export async function getToken()
 let apiUrl = `${BASE_URL}/handler/getToken`
{    
    let response = await axios.get(apiUrl)  


        return response.data.token;
        //i don't know exactly what the api returns so it may be diferent

}

export async function getData(token, param1, param2, param3)
{
    let apiUrl = `${BASE_URL}/handler/getData? token=${token}&param1=${param1}&param2=${param2}&param3=${param3}`


    let response = await axios.post(apiUrl)
    return response.data.response;


}

并且在您的 getBoth() 中只需调用它们,因为函数是异步的,代码只会在它们完成后向前移动

getBoth(){
     setToken(getToken())
     setData(getData(token, param1, param2, param3))
 }
Efraim Jerszurki
2022-03-14