Как вызвать функцию после выполнения цикла map () - PullRequest
0 голосов
/ 17 октября 2019

Я использую реактивную базовую базу данных для сохранения своих носителей в базу данных. У меня есть набор URL-адресов, которые должны быть сохранены в базе данных. Для этого я использую map (), чтобы сохранить один за другим. После сохранения я помещаю успешный URL в массив. Мне нужно вызвать функцию с этим массивом в качестве параметра. Поэтому мне нужно вызвать эту функцию после завершения массива. Я много искал, но не нашел хорошего объяснения этой задаче. Может кто-нибудь помочь мне. Спасибо.

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)

Ответы [ 3 ]

3 голосов
/ 17 октября 2019

Вы можете использовать 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);
}

, а затем вы можете вызывать функцию handleYourTask где угодно:)

0 голосов
/ 17 октября 2019

Просто проверьте длину массива карты и сравните его с ключом карты.

Используйте 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)
  }
})

Я не проверял async await так что используйте его везде, где он установлен.

0 голосов
/ 17 октября 2019

с использованием .map - это хорошо, поэтому вы можете вернуть массив обещаний, которые затем вы можете ждать их разрешения

, в этом случае разрешенное значение в 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);
});
...