在 React 应用程序中连续调用两个异步函数
我有两个
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}¶m1=${param1}¶m2=${param2}¶m3=${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))
}
但即使它是一个在两行上使用
await
的
async
函数,我总是得到相同的
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')
我如何让它真正等待令牌进入后再尝试提取数据?
您正在调用
setToken
,并且期望
token
立即更新,但是
setToken
将异步应用。
您可以使用
useEffect
解决您的问题吗?
useEffect(() => {
getData(token, param1, param2, param3).then(x => {
setData(x.data.response)
})
}, [token])
尝试这个
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}¶m1=${param1}¶m2=${param2}¶m3=${param3}`
let response = await axios.post(apiUrl)
return response.data.response;
}
并且在您的 getBoth() 中只需调用它们,因为函数是异步的,代码只会在它们完成后向前移动
getBoth(){
setToken(getToken())
setData(getData(token, param1, param2, param3))
}