如何取消一个Promise,中止一个网络请求?看完你就学会了

前言

当有一个接口请求响应时间很长,并且请求后还有一些业务处理(会存在于闭包中)。等我们切换到其它页面,这个请求完成后还会处理剩下的业务,导致出现一些错误,例如条件判断错误、状态码错误等等

需求

所以我们有了需求,在特定时机的时候要取消请求和取消Promise让后续的业务代码不在执行,
Promise的取消在业务当中用到的地方比较多的。

我们来说下怎么取消Promise或者中止网络请求

AbortController

介绍一个冷门且有用的 JavaScript api AbortController

AbortController 接口表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求。

你可以使用 AbortController.AbortController() 构造函数创建一个新的 AbortController。使用 AbortSignal 对象可以完成与 DOM 请求的通信。

构造函数

AbortController.AbortController()
创建一个新的 AbortController 对象实例。

属性

AbortController.signal 只读
返回一个 AbortSignal 对象实例,可以用它与一个 DOM 请求进行通信或者中止该请求。

方法

AbortController.abort()
中止一个尚未完成的 Web(网络)请求。这能够中止 fetch 请求及任何响应体的消费和流。

中止Promise代码示例

// 创建 AbortController 实例
const controller = new AbortController();
const signal = controller.signal;

// 创建一个 Promise
const myPromise = new Promise((resolve, reject) => {
  // 在这里执行异步操作
  // 例如,模拟一个异步操作,比如 setTimeout
  const timeoutID = setTimeout(() => {
    // 注意:在执行异步操作之前,应该检查是否已经取消了 Promise
    if (signal.aborted) {
      reject(new Error('Promise cancelled'));
    } else {
      // 如果没有取消,则继续执行
      resolve('Promise resolved');
    }
  }, 1000);

  // 监听取消信号
  signal.addEventListener('abort', () => {
    // 如果收到取消信号,则清除异步操作
    clearTimeout(timeoutID);
    // 并拒绝 Promise
    reject(new Error('Promise cancelled'));
  });
});

// 启动异步操作
myPromise.then((result) => {
  console.log(result);
}).catch((error) => {
  console.log(error.message); // 输出 'Promise cancelled'
});

// 在需要取消 Promise 的时候调用
controller.abort();

在这个示例中,当调用 controller.abort() 时,会触发 Promise 的取消操作。这样,即使异步操作尚未完成,也会在下一次检查取消信号时终止 Promise,并执行相应的拒绝操作。

中止fetch示例

// 创建 AbortController 实例
const controller = new AbortController();
const signal = controller.signal;

// 创建一个 fetch 请求
const myFetch = fetch('https://api.example.com/data', { signal });

// 监听取消信号
signal.addEventListener('abort', () => {
  console.log('Fetch aborted');
});

// 启动 fetch 请求
myFetch
  .then(response => {
    // 处理响应
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => {
    // 处理数据
    console.log(data);
  })
  .catch(error => {
    // 捕获错误
    console.error('Error during fetch:', error);
  });

// 在需要取消 fetch 请求的时候调用
controller.abort();

在这个示例中,当调用 controller.abort() 时,会触发 fetch 请求的取消操作。这会导致 fetch 请求的 then 方法中的 catch 块被触发,并打印出错误消息。

在这里插入图片描述

提前终止后这个请求在 network 面板中的 status 显示为 canceled

有了这个 api 之后,浏览器就能提前终止请求进而节约一些用户带宽。

主流浏览器基本都兼容,可放心使用

在这里插入图片描述

  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值