使用文件输入元素后,我希望随后上传所选文件。使用FileReader读取文件是异步的,因此我尝试使用promise来推迟上传函数调用。但是,当vm.upload()
数组尚未填充时,vm.files
会被调用,但它无法正常工作。顺便说一句,承诺没有错误。
为什么承诺不会等待/推迟'?可能是因为我应该更接近异步代码(在map方法中),但我不确定为什么?
let filesPromise = inputFiles => {
return new Promise((resolve, reject) => {
inputFiles.filter(file => !this.queue.some(f => file.name === f.name))
.map(file => {
file.__size = humanStorageSize(file.size)
if (this.noThumbnails || !file.type.startsWith('image')) {
this.queue.push(file)
}
else {
const reader = new FileReader()
reader.onload = (e) => {
let img = new Image()
img.src = e.target.result
file.__img = img
this.queue.push(file)
this.__computeTotalSize()
}
reader.readAsDataURL(file)
}
return file
})
resolve(inputFiles)
reject(new Error('An error occurred in filesPromise'))
})
}
filesPromise(eventFiles)
.then(eventFiles => vm.files.concat(eventFiles))
.then(() => vm.upload())
.catch(error => console.log('An error occurred: ', error))
答案 0 :(得分:0)
正如@baao评论的那样,包含异步代码(FileReader事件)的map
方法将继续而不是等待。要解决这个问题,需要将FileReader放入Promise并继续使用map
与Promises一起构建一个由Promise-elements组成的数组。在此阵列上,您随后可以运行Promise.all
。此代码有效:
let filesReady = [] // List of image load promises
files = inputFiles.filter(file => !this.queue.some(f => file.name === f.name))
.map(file => {
initFile(file)
file.__size = humanStorageSize(file.size)
file.__timestamp = new Date().getTime()
if (this.noThumbnails || !file.type.startsWith('image')) {
this.queue.push(file)
}
else {
const reader = new FileReader()
let p = new Promise((resolve, reject) => {
reader.onload = (e) => {
let img = new Image()
img.src = e.target.result
file.__img = img
this.queue.push(file)
this.__computeTotalSize()
resolve(true)
}
reader.onerror = (e) => {
reject(e)
}
})
reader.readAsDataURL(file)
filesReady.push(p)
}
return file
})
if (files.length > 0) {
vm.files = vm.files.concat(files)
Promise.all(filesReady)
.then(() => vm.upload())
.catch(error => console.log('An error occurred: ', error))
}