promise取消方案

文章类型:ES6

发布者:hp

发布时间:2025-05-06

一:引言

在js中,Promise 一旦被创建,就会一直执行直到成功(resolve)或失败(reject)。可以通过一些手动的方式来模拟取消 Promise 的效果,那么有什么办法能取消请求呢?

二:方案

(1)原生方案

1:忽略 Promise 的结果

const promise = new Promise((resolve, reject) => {  // 执行异步操作...});// 不处理 Promise 的结果

2:基于标志位的取消

 Promise 内部逻辑中检测外部变量状态,手动触发终止

   let isCancelled = false;
new Promise((resolve, reject) => {
  const timer = setTimeout(() => {
    if (!isCancelled) resolve('完成');
  }, 1000);
  // 提供外部取消方法
  window.cancel = () => { 
    clearTimeout(timer);
    isCancelled = true;
    reject(new Error('已取消'));
  };
});

3:结合 AbortController

通过中断底层操作实现取消‌

const controller = new AbortController();
fetch(url, { signal: controller.signal })
  .then(res => res.json())
  .catch(err => {
    if (err.name === 'AbortError') console.log('请求已取消');
  });
controller.abort(); // 触发取消

(2)三方库方案

   1:‌p-cancelable =>通过包装 Promise 提供 cancel() 方法

const { default: PCancelable } = require('p-cancelable');
const promise = new PCancelable((resolve, reject, onCancel) => {
  onCancel(() => { /* 清理逻辑 */ });
  setTimeout(resolve, 5000);
});
promise.cancel(); // 手动取消

2:‌Bluebird‌ =>提供 .cancel() 方法及超时控制

const Bluebird = require('bluebird');

// 创建可取消的 Promise
const promise = new Bluebird((resolve, reject, onCancel) => {
  const timer = setTimeout(() => resolve('操作完成'), 3000);
  
  // 注册取消回调
  onCancel(() => {
    clearTimeout(timer);
    console.log('清理定时器');
  });
});

// 触发取消
promise.cancel(); // 此时会执行 onCancel 回调并终止 Promise

三:总结

1:所有方法均为逻辑层终止,无法强制停止已提交的异步操作

2:优先使用 AbortController 处理可中断的 API(如 fetch),其他场景选择标志位或第三方库‌