如何等待 React Native Image Picker 回调函数响应?

问题描述

我想做一个函数,将从 react-native-image-picker 中选取的照片上传到 firestore,然后返回上传图像的 URL 值。照片上传成功,我可以在控制台中打印下载 URL,问题是当我尝试在函数中返回 URL 时,它是未定义的。我尝试使用异步函数在返回值之前等待图像选择器响应完成,但它仍然返回 {"_U": 0,"_V": 0,"_W": null,"_X": null} .

uploadImg: async () =>{
        await ImagePicker.launchImageLibrary({ mediaType: 'photo' },response => {
            if (response.error) {
                alert('Something went wrong');
            } else {
                try {
                    const { path,uri } = response;
                    const fileSource = Platform.OS === 'android' ? uri : path;
                    const { fileName } = response;
                    const storageRef = storage().ref(fileName);
                    
                    storageRef.putFile(fileSource).on('state_changed',snapshot => {
                        switch (snapshot.state) {
                            case 'running':
                                setimageURI(null);
                                break;
                            case 'success':
                                snapshot.ref.getDownloadURL().then(downloadURL => {
                                    setimageURI(downloadURL);
                                    //This console log works,and actually prints the correct url
                                    console.log(`Download URL ${downloadURL}`); 
                                });
                                break;
                            default:
                                break;
                        }
                        
                    });
                } catch (error) {
                    console.log(error)
                }
            }
        }); 
        return imageURI;
    }

我很确定问题不在于状态、上传图片或图像选择器响应。这可能是异步函数错误用法

解决方法

async/await 的一个非常基本的用法是这样的:

const someCuteAsyncFunc = async () => {
  try {
    let promise = new Promise((resolve,reject) => {
       setTimeout(() => resolve("done!"),1000)
    });

    let result = await promise; // wait until the promise resolves (*)

    alert(result); // "done!"
  } catch (error) {
    console.error(error);
  }
}

基于this example

鉴于您的代码、try/catch、if/else、switch 和最后的 return,我认为您需要首先简化函数以确保从 Promise 返回图像。关于这个话题 here 有一个很好的答案。

,

这是因为您在 firebase 调用完成执行之前从函数返回。我对您的代码进行了一些更新,以便该函数可以等待 Firebase 响应。

uploadToFirebase: ( fileName,filesource )=>new Promise((resolve,reject)=>{
  const storageRef = storage().ref(fileName);
  storageRef.putFile(fileSource).on('state_changed',snapshot => {
    switch (snapshot.state) {
      case 'running':
        setImageURI(null);
        break;
      case 'success':
        snapshot.ref.getDownloadURL().then(downloadURL => {
          setImageURI(downloadURL);
          //This console log works,and actually prints the correct url
          console.log(`Download URL ${downloadURL}`); 
        });
        break;
      default:
        break;
    }
    resolve();
  });
})
uploadImg: async () =>{
  let response = await ImagePicker.launchImageLibraryAsync({ mediaType: 'photo' });
  if (response.error) {
    alert('Something went wrong');
  } else {
    const { path,uri } = response;
    const fileSource = Platform.OS === 'android' ? uri : path;
    const { fileName } = response;
    await uploadToFirebase(fileName,fileSource)
  }
  return imageURI;
}