在继续功能之前等待图像上传的响应 [英] await response of image upload before continue function

查看:100
本文介绍了在继续功能之前等待图像上传的响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在为数组中的多个图像开发上传功能.经过很多努力后,我终于可以使用上传功能了,并且图像显示在Firebase数据库中.但是,我还没有找到一种可行的方法来确保我的上传功能完成后再继续.

So I am working on a upload function for multiple images in an array. After a lot of struggling I have finally got my upload function to work and the images are showing up in the Firebase Database. However I have yet to find out a working way to make sure my upload function completes before continuing.

以下是我正在调用上载函数并尝试将响应存储在上载网址中的部分,上载网址变量随后在分派函数中用于将上载网址与其他数据一起存储.

Below is the part were I am calling the upload function and try to store the response in uploadurl, the uploadurl variable is later used in the dispatch function to store the url with other data.

   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(

因此图像上传功能在下面.这样做的目的是要上传图像,但是无法正确启动.then调用以获取DownloadURL,并且.then图像也无法正常工作.

So the image upload function is below. This works to the point that the images are uploaded, however the .then call to get the DownloadURL is not started correctly and the .then images also is not working.

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之后,只有这样,我用于分发其余数据的调度功能才应该继续.我如何确保这种情况按预期发生?

So I want to return the imagesArray, AFTER, all the photos are uploaded. So the imagesArray is then set as uploadURL in the first function? After all images URL are set in imagesArray and passed to uploadURL, only then my dispatch function to upload the rest of the data should continue. How can I make sure this is happening as expected?

我现在已经改变了很多次,因为我一直以不同的方式发送信息,这让我完全茫然如何继续:(

I have changed this so many times now because I keep getting send to different ways of doing this that I am completely at a loss how to continue now :(

推荐答案

您的大多数uploadImages()代码都是正确的,但是在许多地方,您并未从每个异步操作中返回承诺.

Most of your uploadImages() code was correct, however in many places you didn't return the promise from each asynchronous action.

在处理基于数组的大量异步任务时,建议

When working with lots of asynchronous tasks based on an array, it is advised to map() the array to an array of Promises rather than use a for loop. This allows you to build an array of promises that can be fed to Promise.all() without the need to initialise and push to another array.

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);
  })

如果任何包含的承诺失败,则以上代码段将失败.要静默忽略单个错误或推迟它们在以后处理,您只需在映射数组步骤内部添加一个catch().

The above snippet will fail if any of the contained promises fail. To silently ignore individual errors or defer them to handle later, you just add a catch() inside the mapped array step.

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

更新的uploadImages()代码

通过这些更改更新代码,将得到以下结果:

Updated uploadImages() code

Updating your code with these changes, gives the following result:

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);
        });
};

这篇关于在继续功能之前等待图像上传的响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆