SOURCE

/**
 * 取消请求
 */

function CancelablePromise() {
  this.pendingPromise = null;
}

// 包装一个请求并取消重复请求
CancelablePromise.prototype.request = function (requestFn) {
  if (this.pendingPromise) {
    this.cancel("取消重复请求");
  }
  const _promise = new Promise((resolve, reject) => (this.reject = reject));
  this.pendingPromise = Promise.race([requestFn(), _promise]);
  return this.pendingPromise;
};

// 取消当前请求
CancelablePromise.prototype.cancel = function (reason) {
  this.reject(new Error(reason));
  this.pendingPromise = null;
};

// ----------下面是测试用例------------

// 模拟一个异步请求函数
function createRequest(delay) {
  return () =>
    new Promise((resolve) => {
      setTimeout(() => {
        resolve("done");
      }, delay);
    });
}


const cancelPromise = new CancelablePromise();

// 前四个请求将被自动取消
for (let i = 0; i < 5; i++) {
  cancelPromise
    .request(createRequest(1000))
    .then((res) => console.log(res,`err-${i+1},最后一个`)) // 最后一个 done
    .catch((err) => console.error(err,`err-${i+1}`)); // 前四个 error: 取消重复请求
}

// 设置一个定时器等3s,让前面的请求都处理完再继续测试
setTimeout(() => {
  // 手动取消最后一个请求
  cancelPromise
    .request(createRequest(1000))
    .then((res) => console.log(res))
    .catch((err) => console.error(err,'err-手动取消')); // error:手动取消
  cancelPromise.cancel("手动取消");
}, 3000);

// 设置一个定时器等4s,让前面的请求都处理完再继续测试
setTimeout(() => {
  cancelPromise
    .request(createRequest(1000))
    .then((res) => console.log(res)) // done
    .catch((err) => console.error(err,'最后一条'));
}, 4000);
console 命令行工具 X clear

                    
>
console