將函數做爲參數傳遞解決異步問題

時間: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

相關文章
相關標籤/搜索