以下代码循环遍历某些表单字段。如果该字段是必须上载的文件,则会运行api.uploadPhoto
功能(在上传照片后设置有效负载)。如果直接设置有效负载时该字段是正常输入:
formFields.forEach(field => {
if (hasUploadFiles(field)) {
uploadPhotoPromise = new Promise((resolve, reject) => {
uploads.queued.push(file)
api.uploadPhoto(file, field).then(uploadedPhoto => {
uploads.finished.push(field)
if (uploads.queued.length === uploads.finished.length) {
payload[field.name] = uploadedPhoto
resolve()
} else {
reject()
}
}).catch(error => {
console.log('error:', error)
reject()
})
}).catch(error => {
console.log('error:', error)
})
} else {
payload[field.name] = field.value
}
})
Promise.all([uploadPhotoPromise]).then(values => {
// update action
}
代码有效。但是,所有catch
使它看起来有些混乱。
我尝试删除它们,但如果删除其中的任何一个代码就会挂起(Promise.all
中的代码永远不会运行)。为什么是这样?如何重构这些代码而不使用所有那些catch语句而不使其挂起?
原始代码(加上Bergi建议的修改):
const buildingFormPromise = utils.mapDeep(this.buildingForm.schema, field => {
if (!field.name) return // fields not in the database
else if (utils.hasUploadFiles(field)) {
utils.eachCall(field.value, (file, index) => {
field.userId = this.user.id
this.uploads.queued.push(file)
this.$set(this.uploads.queued, index, { progress: 30 })
return api.uploadPhoto(file, field).then(uploadedPhoto => {
this.$set(this.uploads.queued, index, { progress: 100 })
return loadImage(uploadedPhoto, () => {
this.uploads.finished.push(field)
if (this.uploads.queued.length === this.uploads.finished.length) {
console.log('This runs after the code inside Promise.all')
buildingPayload[field.name] = uploadedPhoto
}
})
})
})
} else {
return Promise.resolve(buildingPayload[field.name] = field.value)
}
})
Promise.all([buildingFormPromise]).then(values => {
console.log('This runs before the files are uploaded')
})
答案 0 :(得分:1)
你需要将所有承诺的数组传递给Promise.all
,你应该避免使用Promise
constructor antipattern。如果您不想处理单个上传失败,可以将.catch
移至最后。
var fieldValuePromises = formFields.map(field => {
if (hasUploadFiles(field)) {
return api.uploadPhoto(file, field).then(uploadedPhoto => {
return payload[field.name] = uploadedPhoto;
});
} else {
return Promise.resolve(payload[field.name] = field.value);
}
});
Promise.all(fieldValuePromises).then(values => {
// update action
}).catch(error => {
// at least one upload failed
console.log('error:', error)
});