簡體   English   中英

如何等待 promise 在 array.map 方法中解析?

[英]how to wait for promise resolve in array.map method?

我想將照片上傳到 firebase 存儲。

在 React 組件的 state 中,我有帶有照片的數組。 照片是用戶通過文件輸入瀏覽的文件。 如果文件需要上傳到存儲,照片的屬性.needUploadtrue

這里是上傳 function:

uploadPhotos = () => {
    let photosToSave = []
    if (this.state.photos.length) {
      photosToSave = this.state.photos
        .filter(photo => photo.needUpload && true)
        .map(photo => {
          const extensionPattern = /(?:\.([^.]+))?$/
          const fileName = photo.value.name
          const fileExtension = extensionPattern.exec(fileName)[1]
          const newFileName = new Date().getTime()
          const fileLocation = storageRef.child('estateObjects/' + newFileName + '.' + fileExtension)

          return new Promise(resolve => {
            fileLocation.put(photo.value).on(
              firebase.storage.TaskEvent.STATE_CHANGED,
              snapshot => {
                //let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
              },
              null,
              () => {
                fileLocation.getDownloadURL().then(url => {
                  resolve({ url: url, file: newFileName + '.' + fileExtension })
                })
              }
            )
          })
        })
      return Promise.all(photosToSave).then(response => {
        return response
      })
    } else return Promise.all(photosToSave).then(response => [])
  }

主要問題是,當上傳開始時,它(耐心地)等待,我想上傳前 2-3 個文件,然后在“解決”數組中我得到重復的數組元素。 所以有些事情出錯了,但我不明白是什么......

也許問題出在新文件名上?? 當文件重命名時 new Date.getTime() 為幾個文件返回相同的時間,導致它們同時上傳?

在此處輸入圖像描述

map 循環運行速度非常快,因此迭代之間的時間不會改變

所以,我建議你使用index來保證文件名的唯一性

 uploadPhotos = () => { let photosToSave = []; if (this.state.photos.length) { photosToSave = this.state.photos.filter(photo => photo.needUpload && true).map((photo, index) => { const extensionPattern = /(?:\.([^.]+))?$/; const fileName = photo.value.name; const fileExtension = extensionPattern.exec(fileName)[1]; const newFileName = `${new Date().getTime()}_${index}`; const fileLocation = storageRef.child('estateObjects/' + newFileName + '.' + fileExtension); return new Promise(resolve => { fileLocation.put(photo.value).on(firebase.storage.TaskEvent.STATE_CHANGED, snapshot => {//let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100 }, null, () => { fileLocation.getDownloadURL().then(url => { resolve({ url: url, file: newFileName + '.' + fileExtension }); }); }); }); }); return Promise.all(photosToSave).then(response => { return response; }); } else return Promise.all(photosToSave).then(response => []); }

我認為在 newFileName 上添加同步方法的替代方法可以工作。

var time = ''; //Global variable
function getTime() {
   if(new Date().getTime() === time){return getTime()}
   else time = new Date().getTime();
   return time;
}

這是一個示例,說明如何在具有 map 的陣列上迭代執行速度快於時鍾更改之間的毫秒數。

 [...Array(7).keys()].map(v=> console.log(new Date().getTime()))

對於 7 個項目,它主要只創建一個 output,但有時它會產生 2 個不同的值,如下所示:

VM676:2 1572510011727
VM676:5 1572510011728

解決此問題的一種方法是使用uuid 庫創建 uniqe,它將生成唯一的文件名

const uuidv1 = require('uuid/v1');
uuidv1(); // ⇨ '2c5ea4c0-4067-11e9-8bad-9b1deb4d3b7d'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM