【问题标题】:React how to call 1 promise after the previous promise is finish?在前一个承诺完成后反应如何调用 1 个承诺?
【发布时间】:2021-06-19 16:13:48
【问题描述】:

我有一个具有这种结构的 React 钩子。我想要做的是,在完成调用getUserJoinedSlotList() 并获得结果之后,然后我想调用getAllAvailableSlot() 将结果设置到useState 钩子中。

const [joinedSlotList, setJoinedSlotList] = useState(null)
const [availableSlotList, setAvailableSlotList] = useState(null)
const [isAllSlotLoading, setIsAllSlotLoading] = useState(true)

const getJoinedList = () => {
        getUserJoinedSlotList()
            .then(res => {
                setIsLoading(false)
                setJoinedSlotList(res.joined_slot)
            })
            .catch(error => {
                setIsLoading(false)
                setErrorMsg(error.message)

            })
    }


const getAvailableSlotList = () => {
        getAllAvailableSlot()
            .then(res => {
                setIsAllSlotLoading(false)  // this setting not working, at the 2nd API call
                setAllAvailableSlotList(res.slot)
            })
            .catch(error => {
                setAvailableErrMsg(error.message)
                setIsAllSlotLoading(false)
            })
    }

useEffect(() => {
        if (user !== null) {
            getJoinedList()
         }
    }, [user])

这是 getAvailableSlot() 的代码,我使用的是 Aws 放大,所以它实际上返回了 GET 请求的承诺

import { API } from 'aws-amplify';

export const getAllAvailableSlot = async () => {
    let path2 = path + '/list_all'

    return API.get(apiName, path2)
}

我尝试了什么:

getAvailableSlotList作为getJoinedList()的回调函数放入,像这样:

const getJoinedList = (callback) => {
        getUserJoinedSlotList()
            .then(res => {
                setIsLoading(false)
                setJoinedSlotList(res.joined_slot)
            })
            .catch(error => {
                setIsLoading(false)
                setErrorMsg(error.message)

            })

        callback()
    }

then
useEffect(() => {
        if (user !== null) {
            getJoinedList(getAvailableSlotList) // put in as call back here
         }
    }, [user])

通过这个,getAllAvailableSlot 被调用,我得到了结果。但是调用setAvailableSlotList后结果没有设置,setIsAllSlotLoading(false)也不行,还是true

然后我尝试这样调用:

const getJoinedList = () => {
        getUserJoinedSlotList()
            .then(res => {
                setIsLoading(false)
                setJoinedSlotList(res.joined_slot)

               

                getAvailableSlotList() // here call the function 
            })
            .catch(error => {
                setIsLoading(false)
                setErrorMsg(error.message)

            })
    }

同样,结果与上述尝试相同。

然后我也这样尝试:

const calling = async () => {
        await getJoinedList()
        await getAvailableSlotList() //setAvailableSlotList and setAllIsLoading is not working, the 2ND CALL
    }

useEffect(() => {
        if (user !== null) {
            
                //getJoinedList()
                calling()
            
        }
    }, [user])

但是getAvailableSlotList() 设置的钩子仍然没有生效。

具体问题:

我注意到,第二次API调用成功,但是我调用的设置挂钩的后续函数,它没有任何效果。

意味着: getJoinedList() 中的所有内容都运行良好。但是当到达getAvailableSlotList()时,我可以从中得到API结果,但是setAvailableSlotListsetIsAllSlotLoading都不能在值中设置

问题:

  1. 1个API调用完成后如何调用另一个API?

  2. 如何在第 2 次 API 调用时设置 react hooks?

【问题讨论】:

  • 你能分享getAllAvailableSlot()的代码吗?第二次尝试在我看来是正确的。我的猜测是它从未到达.then 块。
  • @ClaireLin 当然,等一下
  • @ClaireLin 我实际上使用的是 Aws 放大,所以我只是从 Get 请求中返回一个承诺。我刚刚更新了问题,把我的头发扯掉了..哈哈
  • 您尝试的第二种方法应该有效:codesandbox.io/s/romantic-bhaskara-odw6i?file=/src/App.js
  • @ken 写了一个正确的答案,并详细解释了为什么第一次/第三次尝试不起作用。希望对您有所帮助!

标签: javascript reactjs


【解决方案1】:

您的第二次尝试应该会奏效。这是一个简化的沙盒示例:https://codesandbox.io/s/romantic-bhaskara-odw6i?file=/src/App.js

关于第一次和第三次尝试出错的地方的一点解释:

第一次尝试即将完成,只是您需要将callback() 移动到.then() 块内,这实际上将您带到第二次尝试。

您使用了 async/await 的第三个请求,但问题是 getJoinedList()getAvailableSlotList() 都没有返回 Promise,因此这两个请求将在同一时间发送,而无需一个等待另一个先解决。

【讨论】:

    【解决方案2】:

    最简单的解决方案实际上是通过链接将整个 getAllAvailableSlot() 函数添加到 getUserJoinedSlotList() 中。我看到你已经在使用它了,所以我不需要深入解释它。

    getUserJoinedSlotList().then(res => {
        --- logic ---
        getAllAvailableSlot().then(res2 => {
           -- logic ---
        }
    }
    

    【讨论】:

      【解决方案3】:

      然后链接和它的配对可以在这里工作。

      await getUserJoinedSlotList()
          .then(res => /*assign hooks data*/)
          .then(() => getAllAvailableSlot())
          .then(availableSlot => /*assign availableSlot data*/)
          .catch(e => console.log(e))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-22
        • 2016-02-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多