首页 > 解决方案 > Promise.all 不等待状态更新

问题描述

我有一个函数可以一次上传多个文件,为此,我必须等到所有文件都上传完毕,然后我想调用一个函数。

我有两个钩子

    const [attachments, setAttachments] = useState([]);
    const [uploadedAttachments, setuploadedAttachments] = useState([]);

attachments包含选定的文件,然后在上传文件时,我将存储一些关于它的元数据uploadedAttachments,我需要在其中发送另一个调用。

所以在上传按钮按下时,我正在调用这个函数:

async function uploadAttachments(userID, id) {
        await Promise.all(
            attachments.map(async (val, index) => {
                await services.uploadAttachment(val, userID, id).then((res) => {
                    setuploadedAttachments([...uploadedAttachments, { "name": res.name, "size": res.size }])
                }).catch((error) => {
                    Alert.alert("Error", error)
                })
            })).then(() => {
                console.log(JSON.stringify(uploadedAttachments))
            }).catch((e) => {
                console.log("ERROR: " + e)
            })
}

JSON.stringify(uploadedAttachments)打印件,[]但如果我调用console.logres之前setuploadedAttachments的内容,我看到我收到了响应,这意味着setuploadedAttachments正在更新,但我打印的地方显示了空数组。那么,我如何确保它await,以便在Promise.all完成后我可以看到它?

更新

我的问题不是useState set 方法的重复,没有立即反映变化

我在等待所有的承诺兑现。每个承诺在返回我一些数据时都会将其添加到我正在使用useState钩子处理的数组中。useEffect是的,它没有立即反映更改,我已尝试按照假定的重复问题中的建议将其放入钩子中。

useEffect(() => {
     setuploadedAttachments([...uploadedAttachments, { "name": res.name, "size": res.size }])
}, [])

Error它在标题中显示警报,但没有错误消息。简而言之,它不起作用。

更新 2

根据我所做的评论

async function uploadAttachments(userID, id) {
        await Promise.all(
            attachments.map(async (val, index) => {
                await services.uploadAttachment(val, userID, id).then((res) => {
                    return res
                }).catch((error) => {
                    Alert.alert("Error", error)
                })
            })).then((responses) => {
                console.log(JSON.stringify(responses))
            }).catch((e) => {
                console.log("ERROR: " + e)
            })
}

services.uploadAttachment功能是

async function uploadAttachment(val, userID, id) {

    let fullURL = BASE_URL + '/uploadFile'
    
    const data = new FormData()
    data.append(...

    const config = {
       ...
    };

    return new Promise((res, rej) => {
        axios.post(fullURL, data, config).then((response) => {
            res(response.data)
        }).catch((error) => {
            console.log(error)
            Alert.alert("Error Occured", error);
        })
    })
}

标签: react-nativepromisereact-hooksuse-state

解决方案


推荐阅读