React 如何在上一个承诺完成后调用 1 个承诺?

时间:2021-06-18 20:14:12

标签: javascript reactjs

我有一个具有这种结构的 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. 如何在第二次 API 调用时设置 React 钩子?

3 个答案:

答案 0 :(得分:1)

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

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

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

第三个您使用了 async/await 但问题不是 getJoinedList() 也不是 getAvailableSlotList() 返回 Promise,因此两个请求将大约在同一时间发送,而不会等待另一个先解决。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

然后链接及其配对可以在这里工作。

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