【问题标题】:await response of image upload before continue function在继续功能之前等待图像上传的响应
【发布时间】:2020-04-01 16:04:54
【问题描述】:

所以我正在为数组中的多个图像开发上传功能。经过一番努力,我终于让我的上传功能正常工作,并且图像显示在 Firebase 数据库中。但是,我还没有找到一种工作方法来确保我的上传功能在继续之前完成。

下面是我调用上传函数并尝试将响应存储在uploadurl中的部分,uploadurl变量稍后在调度函数中用于存储url和其他数据。

   try {
            uploadurl = await uploadImages()
            address = await getAddress(selectedLocation)
            console.log(uploadurl)
            if (!uploadurl.lenght) {
                Alert.alert('Upload error', 'Something went wrong uploading the photo, plase try again', [
                    { text: 'Okay' }
                ]);
                setIsLoading(true);
                return;
            }

            dispatch(

所以图片上传功能如下。这适用于图像已上传,但是获取 DownloadURL 的 .then 调用未正确启动,并且 .then 图像也无法正常工作。

uploadImages = () => {
    const provider = firebase.database().ref(`providers/${uid}`);
    let imagesArray = [];
    try {
        Promise.all(photos)
            .then(photoarray => {
                console.log('all responses are resolved succesfully')
                for (let photo of photoarray) {
                    let file = photo.data;
                    const path = "Img_" + uuid.v4();
                    const ref = firebase
                        .storage()
                        .ref(`/${uid}/${path}`);
                    var metadata = {
                        contentType: 'image/jpeg',
                    };
                    ref.putString(file, 'base64', metadata).then(() => {
                        ref
                            .getDownloadURL()
                            .then(images => {
                                imagesArray.push({
                                    uri: images
                                });
                                console.log("Out-imgArray", imagesArray);

                            })
                    })
                };
                return imagesArray
            })
    } catch (e) {
        console.error(e);
    }
};

所以我想在所有照片上传之后返回 imagesArray。那么在第一个函数中将 imagesArray 设置为 uploadURL 呢?在 imagesArray 中设置所有图像 URL 并传递给 uploadURL 之后,我的调度函数才能继续上传其余数据。如何确保这按预期进行?

我现在已经改变了很多次,因为我不断地被发送到不同的方式来做这件事,我完全不知道现在如何继续:(

【问题讨论】:

  • 在调用者中使用let photoarray = await Promise.all(photos); 并将photoarray 传递给uploadImages() 会更好。此外,uiduuid 应该被传递(如果它们确实是常量)。

标签: firebase function react-native promise image-uploading


【解决方案1】:

您的大部分uploadImages() 代码是正确的,但是在许多地方您没有从每个异步操作中返回承诺。

快速回避:处理许多承诺

在处理大量基于数组的异步任务时,建议map() 将数组转换为 Promises 数组,而不是使用 for 循环。这使您可以构建一个可以提供给 Promise.all() 的 Promise 数组,而无需初始化并推送到另一个数组。

let arrayOfPromises = someArray.map((entry) => {
    // do something with 'entry'
    return somePromiseRelatedToEntry();
  });

Promise.all(arrayOfPromises)
  .then((resultsOfPromises) => {
    console.log('All promises resolved successfully');
  })
  .catch((err) => {
    // an error in one of the promises occurred
    console.error(err);
  })

如果任何包含的承诺失败,上述 sn-p 将失败。要静默忽略个别错误或将它们推迟到以后处理,您只需在映射数组步骤中添加 catch()

let arrayOfPromises = someArray.map((entry) => {
    // do something with 'entry'
    return somePromiseRelatedToEntry()
      .catch(err => ({hasError: true, error: err})); // silently ignore errors for processing later
  });

更新uploadImages()代码

使用这些更改更新您的代码,会产生以下结果:

uploadImages = () => {
    const provider = firebase.database().ref(`providers/${uid}`);
    // CHANGED: removed 'let imagesArray = [];', no longer needed

    return Promise.all(photos) // CHANGED: return the promise chain
        .then(photoarray => {
            console.log('all responses are resolved successfully');
            // take each photo, upload it and then return it's download URL
            return Promise.all(photoarray.map((photo) => { // CHANGED: used Promise.all(someArray.map(...)) idiom
              let file = photo.data;
              const path = "Img_" + uuid.v4();
              const storageRef = firebase // CHANGED: renamed 'ref' to 'storageRef'
                    .storage()
                    .ref(`/${uid}/${path}`);
              let metadata = {
                  contentType: 'image/jpeg',
              };

              // upload current photo and get it's download URL
              return storageRef.putString(file, 'base64', metadata) // CHANGED: return the promise chain
                .then(() => {
                  console.log(`${path} was uploaded successfully.`);
                  return storageRef.getDownloadURL() // CHANGED: return the promise chain
                    .then(fileUrl => ({uri: fileUrl}));
                });
            }));
        })
        .then((imagesArray) => {                       // These lines can
          console.log("Out-imgArray: ", imagesArray)   // safely be removed.
          return imagesArray;                          // They are just
        })                                             // for logging.
        .catch((err) => {
          console.error(err);
        });
};

【讨论】:

  • 你先生是我的英雄!我看不到树之间的福雷斯特(不知道那是不是英语表达,但是嘿......)它就像一个魅力,现在我可以让我的妻子高兴,我可以再次和她一起度过一个晚上而不是我的电脑。非常感谢您的简短解释!
猜你喜欢
  • 2019-08-21
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 2020-01-15
  • 2020-12-24
  • 2012-01-28
  • 2020-01-18
相关资源
最近更新 更多