時間:2018年11月06日
這兩天有這樣的一個需求:在下載按鈕上加一個下載中的loading動畫。如今的狀況是用戶點擊下載按鈕時沒有一點反饋,覺得沒點上,會點擊好幾回,以後一下就下載好幾回。
這種問題是人之常情,因此解決它無可厚非,但是解決的時候遇到了一些比較麻煩的問題。
下載函數在點擊執行按鈕執行函數調用的別的文件的方法,就像下面這樣:promise
// a文件
// 點擊按鈕執行的函數
const main = () => {
downloadFile()
}
// b文件
// 具體下載函數
const downloadFile = () => {
// 下載部分代碼
}
複製代碼
若是僅僅是這樣還好,我能夠在main
函數中加上修改是否展現加載動畫的變量,比方說下面這樣:bash
// a文件
// 點擊按鈕執行的函數
const main = () => {
loading = true;
downloadFile();
loading = false;
}
複製代碼
但是這個downloadFile
函數是個異步函數,因此若是想上面這樣寫的話loading
變量只會瞬間變一下,不會在downloadFile
函數執行完成以後再變成false
。
一開始我是打算用promise
來把main
函數包裹起來,在then
裏面把loading
改爲false
。事實證實這種方法確實可行,只是須要把reslove
傳遞過去,比方說這樣:異步
// a文件
// 點擊按鈕執行的方法
return new Promise((reslove) => {
const main = () => {
loading = true;
downloadFile(reslove);
loading = false;
}
})
// b文件
const downloadFile = (reslove) => {
// 下載部分代碼
reslove();
}
複製代碼
後來思考以後發現這樣的作法其實有點多餘,徹底能夠不用Promise
的。咱們須要新建一個修改loading
值的函數。函數
setLoadingStatus = (err, status) => {
if (err) {
message.error(err.message || err);
return this.exportTableLoading = false;
}
this.exportTableLoading = status;
}
複製代碼
調用方法也比較簡單:動畫
// 有錯
setLoadingStatus(err, false);
// 沒錯
setLoadingStatus(null, true);
複製代碼
以後咱們把這個方法做爲參數傳遞給downloadFile
函數,在downloadFile
函數中調用方法便可。ui
// b文件
const downloadFile = (setLoadingStatus) => {
// 下載部分代碼
if (err) {
setLoadingStatus(err, false);
}
setLoadingStatus(null, true);
}
複製代碼
這裏咱們不用擔憂說setLoadingStatus
函數被調用兩次,由於若是有錯,在執行setLoadingStatus
函數錯誤狀況時,就會直接return
錯誤內容,就算下面有接收到setLoadingStatus
函數的正確狀況也不會執行。
因此總體下來就是這樣的:this
// a文件
// 定義修改loading的函數
setLoadingStatus = (err, status) => {
if (err) {
message.error(err.message || err);
return this.exportTableLoading = false;
}
this.exportTableLoading = status;
}
// 點擊按鈕執行的函數
const main = () => {
loading = true;
downloadFile(setLoadingStatus);
}
// b文件
const downloadFile = (setLoadingStatus) => {
// 下載部分代碼
if (err) {
setLoadingStatus(err, false);
}
setLoadingStatus(null, true);
}
複製代碼
不一樣文件之間也能夠互相調用函數,不用考慮傳遞過去以後就沒法修改loading
值的問題,由於其自己調用的仍是a
文件中的setLoadingStatus
函數。spa