如何等待 react native Image Picker 回调函数响应?

Posted

技术标签:

【中文标题】如何等待 react native Image Picker 回调函数响应?【英文标题】:How to await for the react native Image Picker callback function response? 【发布时间】:2021-01-21 23:08:43 【问题描述】:

我想做一个函数,将从 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;
    

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

【问题讨论】:

【参考方案1】:

这是因为您在 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;

【讨论】:

非常感谢!我确实不得不改变一些小事情,例如将 resolve 移动到 switch 的默认值,以及 resolve 以取得成功。我也使用了不支持异步启动的 react-native-image-picker,所以我不得不迁移到 expo-image-picker。最后在uploadImg() 中,我必须返回一个promise 解决方案,而不是返回imageURI。但是你肯定让我在正确的轨道上解决我的问题,非常感谢! 很高兴它有帮助。我认为resolve 也可能在switch-case 之外,因为默认设置它没有意义。【参考方案2】:

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。

【讨论】:

以上是关于如何等待 react native Image Picker 回调函数响应?的主要内容,如果未能解决你的问题,请参考以下文章

React Native创建项目等待时间长解决

react-native-image-picker 视频的持续时间

如何等待firebase数据获取完成并在react-native中获取不是承诺的值?

如何在 React-Native Fast-Image 组件 TypeScript 中不使用任何内容

React Native:如何检查用户是否已授予gps权限

如何使用 react-native-camera 包获取加载的 Nosuitable image URL 为 null 捕获图像