[英]how to wait for promise resolve in array.map method?
我想將照片上傳到 firebase 存儲。
在 React 組件的 state 中,我有帶有照片的數組。 照片是用戶通過文件輸入瀏覽的文件。 如果文件需要上傳到存儲,照片的屬性.needUpload
為true
。
這里是上傳 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.