在使用 vue + vant@2.13.2
技術棧的項目中,因為上傳文件的接口是單文件上傳,當使用批量上傳時,只能循環(huán)調取接口;然后有校驗內容:需要所有文件上傳成功后才能保存,在文件上傳不成功時點擊保存按鈕,則提示信息:"文件上傳未成功!"
。
我使用 for 循環(huán)調取接口,然后定義了 promiseList
數(shù)組,循環(huán)一次將 promise
對象添加一次,然后使用 Promise.all(promiseList).then(result=>console.log(result))
來改變保存的狀態(tài)。但是發(fā)現(xiàn)打印出的 result 總是空數(shù)組[]
。debugger 代碼的執(zhí)行順序,應該是異步的原因導致的。
如下代碼:
/** 上傳文件組件 */
<van-uploader
name="multipartFile"
multiple
v-model="jobFileList"
:after-read="(file) => afterRead(file, jobFileList)" // 默認寫法參數(shù)只有file對象,如需傳遞其他參數(shù)則需要此種寫法
:before-read="(file) => beforeRead(file, jobFileList)"
:before-delete="(file) => beforeDelete(file, jobFileList)"
:max-count="9"
>
</van-uploader>
下面上傳了一張圖片文件格式;如下圖,其中 fileId、fileName、fileType、fileUrl
為自定義字段,上傳服務器成功后返回的,其他字段為 van-uploader
組件所支持的自有字段。
/** 上傳文件邏輯 */
afterRead(file) {
const _this = this;
this.isFetchDone = 1; // 文件是否全部上傳完成:0是 1否
let promiseList = [];
if (!Array.isArray(file)) {
// 單張圖片上傳
promiseList = [file];
} else {
// 批量上傳
promiseList = file;
}
for (const f of file) {
// 壓縮文件
new Compressor(f.file, {
quality: 0.5,
success(result) {
// blob格式轉換為file格式
f.file= new File([result], result.name, { type: result.type });
const p = _this.uploadFileChange(f);
promiseList.push(p);
},
error(err) {
console.warn(err.message);
},
});
}
// 使用Promise.all()改變保存狀態(tài)
Promise.all(promiseList).then(result=> {
console.log(result); // []
// 所有的文件狀態(tài)都是"done"則代表文件全部上傳完成
const bool = result.every(file => file.status === 'done');
if (bool) {
// 改變保存狀態(tài)為0,可保存
this.isFetchDone = 0;
}
})
}
/** 上傳文件邏輯 */
uploadFileChange(f) {
return new Promise((resolve, reject) => {
f.status = "uploading";
f.message = "上傳中...";
// 上傳圖片要formData類型
const formData = new FormData();
formData.append("multipartFile", f.file);
// 上傳文件接口
uploadFile(formData).then((response) => {
const { data, resultCode, resultMessage } = response;
if (resultCode === 0 && data) {
f.fileId = data.fileId;
f.fileName = data.fileName;
f.fileType = data.fileType;
f.fileUrl = data.fileUrl;
f.status = "done";
f.message = "上傳完成";
resolve(f);
} else {
f.status = "failed";
f.message = "上傳失敗";
reject(resultMessage);
}
}).catch(err => {
f.status = "failed";
f.message = "上傳失敗";
reject(err)
});
})
},
上面代碼的執(zhí)行順序是,先執(zhí)行 for
循環(huán),然后直接執(zhí)行了 Promise.all()
,最后執(zhí)行 promiseList.push()
;因為 for
和 Promise.all()
都是同步代碼,所以在 Promise.all(promiseList)
執(zhí)行時,promiseList
其實是一個空數(shù)組,所以 then
最終返回的是一個空數(shù)組。文章來源:http://www.zghlxwxcb.cn/news/detail-801717.html
我選擇的修改方式是將 for 循環(huán)放到了 Promise.all() 中,如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-801717.html
afterRead(file) {
const _this = this;
this.isFetchDone = 1;
let promiseList = [];
if (!Array.isArray(file)) {
// 單張圖片上傳
promiseList = [file];
} else {
// 批量上傳
promiseList = file;
}
/** 可以將 promiseList.map 單獨封裝成一個函數(shù)放在這里(優(yōu)化代碼) */
Promise.all(
promiseList.map(f => {
return new Promise((resolve, reject) => {
// 壓縮文件
new Compressor(f.file, {
quality: 0.5,
success(result) {
// blob格式轉換為file格式
f.file= new File([result], result.name, { type: result.type });
f.status = "uploading";
f.message = "上傳中...";
// 上傳圖片要formData類型
const formData = new FormData();
formData.append("multipartFile", f.file);
// 上傳文件接口
uploadFile(formData).then((response) => {
const { data, resultCode, resultMessage } = response;
if (resultCode === 0 && data) {
f.fileId = data.fileId;
f.fileName = data.fileName;
f.fileType = data.fileType;
f.fileUrl = data.fileUrl;
f.status = "done";
f.message = "上傳完成";
resolve(f);
} else {
f.status = "failed";
f.message = "上傳失敗";
reject(resultMessage);
}
}).catch(err => {
f.status = "failed";
f.message = "上傳失敗";
reject(err);
})
},
error(err) {
console.warn(err.message);
},
});
})
})
).then(result => {
const bool= result.every(file => file.status === 'done');
if (bool) {
this.isFetchDone = 0;
}
})
},
到了這里,關于循環(huán)異步調取接口使用數(shù)組promiseList保存,Promise.all(promiseList)獲取不到數(shù)組內容,then()返回空數(shù)組的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!