0


【前端】在 TypeScript 中使用 AbortController 取消异步请求

在 TypeScript 中使用

AbortController

来取消异步请求,尤其是像

fetch

这样的请求,可以提供一种优雅的方式来中止长时间运行的操作。下面是一个详细的步骤说明,展示如何在 TypeScript 中使用

AbortController

取消

fetch

请求。

步骤 1:创建

AbortController

实例

首先,你需要创建一个

AbortController

实例,并从中获取

signal

对象。这个

signal

对象将在请求中使用,以便在需要时取消请求。

const controller =newAbortController();const signal = controller.signal;

步骤 2:发送带有

signal

的请求

当使用

fetch

发送请求时,传递

signal

作为选项的一部分。如果请求被取消,

fetch

将会抛出一个带有

name

属性为

"AbortError"

的错误。

fetch('/api/data',{ signal }).then(response =>{if(!response.ok){thrownewError(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data =>{console.log(data);}).catch(error =>{if(error.name ==='AbortError'){console.log('Fetch operation was aborted');}else{console.error('Fetch operation failed:', error);}});

步骤 3:取消请求

在某个时刻,如果你决定要取消请求,只需调用

controller.abort()

方法即可。

setTimeout(()=>{
  controller.abort();},3000);// 取消请求将在3秒后发生

示例:完整的代码示例

下面是一个完整的示例,展示了如何使用

AbortController

来取消一个

fetch

请求:

// 示例:使用 AbortController 取消 fetch 请求const controller =newAbortController();const signal = controller.signal;// 在3秒后取消请求setTimeout(()=>{
  controller.abort();},3000);// 发送带有 signal 的请求fetch('/api/data',{ signal }).then(response =>{if(!response.ok){thrownewError(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data =>{console.log('Received data:', data);}).catch(error =>{if(error.name ==='AbortError'){console.log('Fetch operation was aborted');}else{console.error('Fetch operation failed:', error);}});

在使用

AbortController

取消请求后,如果需要重新尝试发送请求,可以采用几种不同的策略。下面将介绍如何在 TypeScript 中实现重新尝试的逻辑。

1. 手动重新尝试

最简单的方法是在请求被取消后手动重新触发请求。这种方法适用于你知道何时应该重新尝试的情况,比如在某些用户操作之后。

const controller =newAbortController();const signal = controller.signal;// 发送带有 signal 的请求fetch('/api/data',{ signal }).then(response =>{if(!response.ok){thrownewError(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data =>{console.log('Received data:', data);}).catch(error =>{if(error.name ==='AbortError'){console.log('Fetch operation was aborted');// 手动重新尝试setTimeout(()=>{
        controller =newAbortController();
        signal = controller.signal;fetch('/api/data',{ signal }).then(response =>{if(!response.ok){thrownewError(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data =>{console.log('Retried and received data:', data);}).catch(error =>{console.error('Retry failed:', error);});},5000);// 5秒后重新尝试}else{console.error('Fetch operation failed:', error);}});
2. 使用重试库

另一种方法是使用重试库,例如

p-retry

或者

retry

,它们可以自动处理重试逻辑,并提供灵活的配置选项。

示例:使用 p-retry

首先安装

p-retry

npminstall p-retry

然后在代码中使用它:

import retry from'p-retry';asyncfunctionfetchData(signal: AbortSignal):Promise<any>{returnfetch('/api/data',{ signal }).then(res => res.json());}retry(()=>fetchData(signal),{ retries:3, factor:2, minTimeout:1000, maxTimeout:3000}).then(data =>{console.log('Received data:', data);}).catch(error =>{console.error('Fetch operation failed:', error);});
3. 自定义重试逻辑

你也可以自己编写重试逻辑,根据需要调整重试次数、间隔时间等参数。

constMAX_RETRIES=3;constRETRY_INTERVAL=1000;// 间隔时间(毫秒)asyncfunctionfetchData(signal: AbortSignal):Promise<any>{returnfetch('/api/data',{ signal }).then(res => res.json());}asyncfunctionretryFetch(signal: AbortSignal, retriesLeft:number=MAX_RETRIES):Promise<any>{try{returnawaitfetchData(signal);}catch(error){if(error.name ==='AbortError'&& retriesLeft >0){console.log(`Fetch operation was aborted, retrying... (${retriesLeft} attempts left)`);awaitnewPromise(resolve =>setTimeout(resolve,RETRY_INTERVAL));returnretryFetch(signal, retriesLeft -1);}else{throw error;}}}retryFetch(signal).then(data =>{console.log('Received data:', data);}).catch(error =>{console.error('Fetch operation failed:', error);});
4. 使用
AbortController

的组合策略

你还可以结合使用

AbortController

和重试逻辑,以实现更复杂的场景。例如,在某些条件下取消请求,并在满足一定条件时重新尝试。

const controller =newAbortController();const signal = controller.signal;// 在满足某些条件下取消请求setTimeout(()=>{if(/* 某些条件 */){
    controller.abort();}},3000);// 发送带有 signal 的请求fetch('/api/data',{ signal }).then(response =>{if(!response.ok){thrownewError(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data =>{console.log('Received data:', data);}).catch(error =>{if(error.name ==='AbortError'){console.log('Fetch operation was aborted');// 根据条件重新尝试if(/* 满足重新尝试的条件 */){const newController =newAbortController();const newSignal = newController.signal;fetch('/api/data',{ signal: newSignal }).then(response =>{if(!response.ok){thrownewError(`HTTP error! Status: ${response.status}`);}return response.json();}).then(data =>{console.log('Retried and received data:', data);}).catch(error =>{console.error('Retry failed:', error);});}}else{console.error('Fetch operation failed:', error);}});

注意事项

  • 兼容性:请确保你的浏览器或 Node.js 版本支持 AbortController。对于不支持的环境,你可能需要考虑使用 polyfills。
  • 信号传播:如果你在请求中使用了中间件(例如代理服务器),请注意 AbortController 的信号可能不会被正确传播。在这种情况下,你可能需要手动处理信号的传播。
  • 资源释放:取消请求后,确保适当释放资源。例如,如果请求涉及文件上传,取消请求后应确保删除临时文件。

使用 AbortController 的好处

  • 更好的用户体验:用户可以在长时间的请求未完成前取消请求,减少无响应的情况。
  • 资源管理:可以避免因长时间未完成的请求而导致的资源浪费。
  • 灵活性:为异步操作提供了一种灵活的控制机制。

通过这种方式,你可以有效地在 TypeScript 中使用

AbortController

来管理异步请求的生命周期。


本文转载自: https://blog.csdn.net/u010690311/article/details/143330277
版权归原作者 奔跑草- 所有, 如有侵权,请联系我们删除。

“【前端】在 TypeScript 中使用 AbortController 取消异步请求”的评论:

还没有评论