如何在請求資料時,顯示載入動畫

wmui發表於2022-02-22

為了優化使用者體驗,我們希望對於資料返回比較慢的介面,能夠顯示一個載入動畫,但是在資料返回比較快的時候我們又不希望顯示這個動畫。下面提供一種方式,來解決這個問題

方法的核心是Promise.race(),簡單回顧下Promise.race使用方法,Promise.race(iterable) 方法接收一個可迭代物件作為引數,返回一個 promise。迭代器中的某個promise解決或拒絕,返回的 promise 就會解決或拒絕,也就是說誰先有響應就返回誰的結果。

const promise1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 500, 'promise 1 resolved');
});

const promise2 = new Promise((resolve, reject) => {
    setTimeout(reject, 100, 'promise 2 rejected');
});

const promise3 = new Promise((resolve, reject) => {
    setTimeout(resolve, 200, 'promise 3 resolved')
});

(async () => {
  try {
      let result = await Promise.race([promise1, promise2, promise3]);
      console.log(result);
  } catch (err) {
      console.error(err);
  }
})();

// 輸出:promise 2 rejected
// 因為promise2最先有響應,所以返回的是cacth到的reject值

基於此我們就有了問題的解決思路:通過編寫一個timeout函式,來判斷是介面先有響應還是timeout函式先有響應,如果timeout先有就說明需要顯示loading,否則就不需要顯示。


// 模擬網路請求
function getUserInfo(user) {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve("user data!"), Math.floor(900*Math.random()));
  });
}

// 模擬介面請求
function showUserInfo(user) {
  return getUserInfo().then(info => {
   // 這裡處理業務邏輯
    console.log(info)

    // return值用來告訴promise.rece()請求完成
    return true;
  });
}

// loading函式
function showSpinner() {
  console.log("please wait...")
}

// 延遲函式
function timeout(delay, result) {
  return new Promise(resolve => {
    setTimeout(() => resolve(result), delay);
  });
}

// 如果300ms後timeout沒有響應,就顯示loading
Promise.race([showUserInfo(), timeout(300)]).then(displayed => {
  if (!displayed) showSpinner();
});

注意: showUserInfo函式一定要有返回值,用來告訴promise.rece()請求完成

如何在請求資料時,顯示載入動畫首發於聚享小站,如果對您有幫助,不要忘記點贊支援一下呦?

相關文章