【日常学习】如何实现延迟loading

293 阅读1分钟

背景

在执行异步请求的时候,如果超过某个时间仍未拿到返回值,则开启一个loading。

分析

设计一个函数,传入timer结束调用的函数异步请求的方法,返回异步请求的结果

  1. 设置一个标识请求成功的flag,let flag = false
  2. 同时执行setTimeout()和异步请求
  3. 当异步请求返回时,flag = true
  4. 如果时间到了但flag === false,则设置loading

实现

// timeoutCallback: 触发loading
// okCallback: 远端请求
function setLoading (timeoutCallback: () => void, okCallback: () => Promise<void>) {
    return new Promise((resolve, reject) => {
        const timer = setTimeout(resolve, 1000, true); // after 1000ms
        const callback = okCallback(); // 返回一个Promise
        let flag = false;
        timer.then(
            if (!flag) {
                timeoutCallback();
            }
        )
        callback.then(
            (value) => {
                flag = true;
                resolve(value); // 暴露请求结果
            },
            (err) => {
                flag = true;
                reject(err); // 暴露请求结果
            }
        )
    }
}

const response = await setLoading(timeoutCallback, okCallback);
// other code ...

由于我们需要返回异步请求的结果,必须等待callback变成settled再执行后面的代码,所以最后直接用Promise对象包裹了整个逻辑。