In order to optimize the user experience, we hope that a loading animation can be displayed for the interface with slow data return, but we do not want to display this animation when the data return is fast. Here is a way to solve this problem

The core of the method is Promise.race() , briefly review the usage of Promise.race , the Promise.race(iterable) method receives an iterable object as a parameter and returns a promise. When a promise in the iterator is resolved or rejected, the returned promise will be resolved or rejected, that is, whoever has the first response will return the result.

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值

Based on this, we have a solution to the problem: by writing a timeout function, we can judge whether the interface responds first or the timeout function responds first. If the timeout occurs first, it means that the loading needs to be displayed, otherwise, no display is required.


// 模拟网络请求
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();
});

Note : The showUserInfo function must have a return value to tell promise.rece() that the request is complete

how to display loading animation

wmui
1.9k 声望177 粉丝

一人一世界