У меня есть простая форма, которая позволяет загружать файлы.
<form @submit.prevent="sendForm" enctype="multipart/form-data">
<input multiple ref="PostFiles" name="PostFiles" type="file" @change="selectFile('add')">
<!-- other fields here -->
<button type="submit" name="Send" value="Send"></button>
</form>
- Метод
selectFile()
вызывает метод uploadFile()
для отправки файлов, выбранных пользователем, на сервер используя axios.post()
запросов. - Если пользователь решает отправить форму в то время, когда загрузка все еще происходит, то ему нужно
await
для selectFile()
завершения перед отправкой.
Это то, что selectFile()
отлично работает. Он ожидает разрешения uploadFile()
, а затем я получаю сообщение об успешном завершении в консоли:
async selectFile(action) {
if (action === 'add') {
// It adds the files to the array this.Form.PostFiles
let PostFiles = this.$refs.PostFiles.files;
if (this.Form.PostFiles == null || this.Form.PostFiles.length === 0) {
this.Form.PostFiles = [...this.Form.PostFiles, ...PostFiles].map(file => { //returns a new array with the file object and metainfo object
return [
file, {
originalFilename: file.name,
uploadedFilename: "",
size: file.size,
type: file.type,
isUploading: false,
isUploaded: false,
uploadProgress: 0,
previewImgSrc: URL.createObjectURL(file)
}
]
});
} else {
PostFiles = Array.from(PostFiles).map(file => {
return [
file, {
originalFilename: file.name,
uploadedFilename: "",
size: file.size,
type: file.type,
isUploading: false,
isUploaded: false,
uploadProgress: 0,
previewImgSrc: URL.createObjectURL(file)
}
]
});
this.Form.PostFiles.push(...PostFiles);
}
}
try {
return Promise.all(
this.Form.PostFiles.map(async (file, i) => {
const File = file[0];
if (this.Form.PostFiles[i][1].isUploaded == false &&
this.Form.PostFiles[i][1].isUploading == false) {
await this.uploadFile({File: File, FileIndex: i});
}
})
)
.then(result => {
console.log("Successfully uploaded all files")
}).catch(err => {
console.log(err)
})
} catch (err) {
console.log(err)
}
}
Метод uploadFile()
загружает файлы, используя axios
, например:
async uploadFile({ File, FileIndex }) {
const FormFile = new FormData();
FormFile.append("UploadFile", File);
this.Form.PostFiles[FileIndex][1].isUploading = true;
return this.$axios.post('/api/post', FormFile)
.then(response => {
this.Form.PostFiles[FileIndex][1].isUploading = false;
this.Form.PostFiles[FileIndex][1].isUploaded = true;
}).catch(err => {
console.log(err)
})
Итак, вот где возникает проблема. Если пользователь нажимает кнопку отправки формы во время загрузки, тогда метод sendForm()
не ожидает, пока selectFile()
выполнит все обещания перед отправкой файла:
async sendForm() {
const FormBody = new FormData();
FormBody.append("PostTitle", this.Form.PostTitle);
FormBody.append("PostDescription", this.Form.PostDescription);
try {
await this.selectFile();
this.$axios.post('/api/post', FormBody).then(response => {
console.log("Form submitted");
}).catch(err => {
console.log(err.response.data.error)
})
} catch (error) {
console.log(error);
}
}
Я получаю сообщение в консоли с надписью «Форма отправлена», хотя может быть еще 3 загрузки. Кажется, что "Форма отправлена" напечатана вскоре после завершения первой загрузки. Почему он не ожидает selectFile()
и как мне это исправить, чтобы он ожидал завершения загрузки всех файлов sh перед отправкой формы?