简体   繁体   English

执行 map() 循环后如何调用 function

[英]How to call a function after map() loop executed

I'm using react-native firebase to save my media into firebase. I have a set of URLs that need to be saved in the firebase. For that, I'm using map() to save one by one.我正在使用 react-native firebase 将我的媒体保存到 firebase。我有一组 URL 需要保存在 firebase 中。为此,我使用 map() 一个一个地保存。 After saving I'm pushing the success URL to the array.保存后,我将成功 URL 推送到数组。 I need to call a function with this array as a parameter.我需要使用此数组作为参数调用 function。 So I need to call this function after the array is completed.所以我需要在数组完成后调用这个function。 I have searched a lot but I did not find a good explanation for this task.我进行了很多搜索,但没有找到对此任务的良好解释。 Can anyone help me.谁能帮我。 Thank you.谢谢。

var mediaArray = []; //array of success callbacks values
var completedMediaSurveysAnswers = [{}, {}, {}]; //object array of URLs and media types
completedMediaSurveysAnswers.map((i) => {
  try {
    const storage = firebase.storage();
    const mRef = storage.ref('portal').child('Survey/Image/user/' + uuidv4() + 'media');
    mRef.putFile(i.urlPath, {
        contentType: i.mediaType
      })
      .on('state_changed', snapshot => {},
        err => {
          console.log('Failed to upload file to firebase storage')
        },
        uploadedFile => {
          // Success
          this.setState({
            mediaPath: uploadedFile.downloadURL
          })
          mediaArray.push(this.state.mediaPath)
        });
  } catch (error) {
    console.log(error)
  }
})

//need to call this function after loop is done
saveAnswers(mediaArray)

You can use Promise or async/await to handle all kind of these situations like this:您可以使用 Promise 或 async/await 来处理所有这些情况,如下所示:

var mediaArray = [];
var completedMediaSurveysAnswers = [{}, {}, {}];

async function handleYourTask() {
  await completedMediaSurveysAnswers.map((i) => {
  try {
    const storage = firebase.storage();
    const mRef = storage.ref('portal').child('Survey/Image/user/' + uuidv4() + 'media');
    mRef.putFile(i.urlPath, {
        contentType: i.mediaType
      })
      .on('state_changed', snapshot => {},
        err => {
          console.log('Failed to upload file to firebase storage')
        },
        uploadedFile => {
          // Success
          this.setState({
            mediaPath: uploadedFile.downloadURL
          })
          mediaArray.push(this.state.mediaPath)
        });
    } catch (error) {
      console.log(error)
    }
  })

  await saveAnswers(mediaArray);
}

and then you can call handleYourTask function anywhere you want:)然后你可以在任何你想要的地方调用handleYourTask function:)

As per my knowledge we can dom something like below.据我所知,我们可以做如下的事情。

Learn From: https://www.codegrepper.com/code-examples/javascript/wait+for+map+to+finish+javascript学习自: https://www.codegrepper.com/code-examples/javascript/wait+for+map+to+finish+javascript

Perform an action after.map() completion:在 .map() 完成后执行一个动作:

var promises = testUserArray.map((item, index) => {
    console.log('item', item)
})

await Promise.all(promises).then(() => {
    console.log('Map Opration Successfully Completed')
})

Example App:示例应用程序:

import React, { useState } from 'react'
import { View, StatusBar, Text, Button } from 'react-native'

export default function App() {

    const [testUserArray, setTestUserArray] = useState(testArray)

    const _testMap = async () => {

        var promises = testUserArray.map((item, index) => {
            console.log('item', item)
        })

        await Promise.all(promises).then(() => {
            console.log('Map Opration Successfully Completed')
        })
    }
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', }}>
            <Button
                title='Test .map()'
                onPress={() => _testMap()}
            />
        </View>
    )
}

const testArray = [
    {
        "id": '1',
        "name": 'User 1'
    },
    {
        "id": '2',
        "name": 'User 2'
    },
    {
        "id": '3',
        "name": 'User 3'
    },
    {
        "id": '4',
        "name": 'User 4'
    },
    {
        "id": '5',
        "name": 'User 5'
    },
]

using.map is good, so you can return an Array of promises which you can then wait for their resolution using.map 很好,所以你可以返回一个承诺数组,然后你可以等待它们的解决

in this case, the resolved value in Promise.all will be what you were pushing into an array... ie this.state.mediaPath在这种情况下,Promise.all 中的解析值将是您推送到数组中的值...即this.state.mediaPath

var completedMediaSurveysAnswers = [{}, {}, {}]; //object array of URLs and media types
var promises = completedMediaSurveysAnswers.map((i) => new Promise((resolve, reject) => {
    try {
        const storage = firebase.storage();
        const mRef = storage.ref('portal').child('Survey/Image/user/' + uuidv4() + 'media');
        mRef.putFile(i.urlPath, {
            contentType: i.mediaType
        }).on('state_changed', snapshot => {}, err => {
            console.log('Failed to upload file to firebase storage');
            resolve(null); // so one failure doesn't stop the whole process
        }, uploadedFile => {
            // Success
            this.setState({
                mediaPath: uploadedFile.downloadURL
            })
            resolve(this.state.mediaPath)
        });
    } catch (error) {
        console.log(error)
        resolve(null); // so one failure doesn't stop the whole process
    }
}));

//need to call this function after loop is done
Promise.all(promises).then(mediaArray => {
    saveAnswers(mediaArray);
});

Just check the length of your map array and compare it with map key.只需检查您的 map 阵列的长度并将其与 map 密钥进行比较。

Use async await to wait till file to upload使用async await等待文件上传

var mediaArray = []; //array of success callbacks values
var completedMediaSurveysAnswers = [{}, {}, {}]; //object array of URLs and media types
completedMediaSurveysAnswers.map(async (i, key) => {
  try {
    const storage = firebase.storage();
    const mRef = storage.ref('portal').child('Survey/Image/user/' + uuidv4() + 'media');
    await mRef.putFile(i.urlPath, {
        contentType: i.mediaType
      })
      .on('state_changed', snapshot => {},
        err => {
          console.log('Failed to upload file to firebase storage')
        },
        uploadedFile => {
          // Success
          this.setState({
            mediaPath: uploadedFile.downloadURL
          })
          mediaArray.push(this.state.mediaPath)
        });

     if( key == (completedMediaSurveysAnswers.length - 1 ) ){
       saveAnswers(mediaArray)
     }
  } catch (error) {
    console.log(error)
  }
})

I don't tested async await so use it wherever its set.我没有测试async await ,所以在它设置的任何地方使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM