為了優化使用者體驗,我們希望對於資料返回比較慢的介面,能夠顯示一個載入動畫,但是在資料返回比較快的時候我們又不希望顯示這個動畫。下面提供一種方式,來解決這個問題
方法的核心是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()請求完成
如何在請求資料時,顯示載入動畫首發於聚享小站,如果對您有幫助,不要忘記點贊支援一下呦?