問題場景:前端通過后端接口下載文件,返回值是一個blob文件,需要通過fileReader.onload()內(nèi)部才能做各種判斷,并且將res.data返回出去,但是fileReader.onload()是一個異步方法,直接reutrn fileReader.onload()是返回undefined。所以問題就是怎么把fileReader.onload()內(nèi)部的變量傳遞出去呢?
一開始是想用閉包,但結(jié)果發(fā)現(xiàn)是undefined,應(yīng)該是fileReader.onload()本身就沒有返回值。結(jié)果就被卡住了。
后來想到一個新辦法。
很簡單,核心就是在第一個.then的處理邏輯中,繼續(xù)返回Promise,然后在下一個Promise的.then中進行return
代碼如下:
/**
* 下載(post請求)
* @param {string} url 請求地址
* @param {object} params 地址參數(shù)
*/
export const downloadPost = async function (url, data = {}, params={}) {
return await axios.post(url,data, {
...params,
responseType: 'blob',
headers: {
'X-AUTH-TOKEN' : getToken(),
},
}).then(res => {
return new Promise((resolve,reject)=>{
let fileReader = new FileReader();
fileReader.onload = function () {
try {
let response = JSON.parse(this.result); // 說明是普通對象數(shù)據(jù),后臺轉(zhuǎn)換失敗
if(typeof response == 'object') {
if (response.code) {
Notification.warning({
title: '提示',
message: `${response.msg}`,
})
return reject(response)
}
}else{
throw('message');
}
} catch (error) {
const name = window.decodeURI(res.headers['content-disposition'].split('=')[1]);
if (window.navigator.msSaveBlob) {
const blobObject = new Blob([res.data]);
window.navigator.msSaveBlob(blobObject, name);
} else {
let link = document.createElement('a');
link.href = window.URL.createObjectURL(res.data);
link.download = name;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
return resolve(res.data)
}
};
fileReader.readAsText(res.data)
})
}).then(res=>{
return res
}).catch(err=>{
return Promise.reject(err);
});
}