软件教程 2025年08月6日
0 收藏 0 点赞 714 浏览 3922 个字
摘要 :

文章目录 一、借助AbortController中断fetch请求 二、在自定义异步函数中运用AbortController (一)使用变量控制异步函数中断 (二)使用变量控制和AbortController对……




  • 一、借助AbortController中断fetch请求
  • 二、在自定义异步函数中运用AbortController
    • (一)使用变量控制异步函数中断
    • (二)使用变量控制和AbortController对比
  • 三、利用Promise.race实现超时中断

JavaScript编程中,我们常常会遇到需要中断正在执行的异步函数的情况。比如在发起网络请求时,用户突然取消操作,或者某个异步任务执行时间过长,我们希望能够及时终止它。接下来,就为大家详细介绍几种常见且有效的中断异步函数的方法

一、借助AbortController中断fetch请求

AbortController是浏览器和Node.js都内置的一个API,它主要用来取消异步操作,像fetch发起的网络请求就可以用它来中断。下面这段代码展示了具体的实现方式:

// 创建一个AbortController实例,用于控制异步操作的终止
const controller = new AbortController();
// 获取信号对象,用于传递给异步操作,以便在需要时中断它
const signal = controller.signal;

// 发起一个fetch请求,并将信号对象传递进去
fetch(\'https://example.com/api/data\', { signal })
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => {
    // 判断错误类型,如果是因为操作被取消导致的错误
    if (error.name === \'AbortError\') {
      console.log(\'请求已被取消\');
    } else {
      // 其他类型的错误,打印错误信息
      console.error(\'请求出错:\', error);
    }
  });

// 在某个时刻,比如用户点击了取消按钮等情况下,调用abort方法取消请求
controller.abort();

在这段代码里,我们先创建了AbortController实例及其信号对象,然后把信号对象传入fetch请求。当调用controller.abort()时,fetch请求就会被中断,并在catch块中捕获到AbortError错误。

二、在自定义异步函数中运用AbortController

除了中断fetch请求,AbortController在自定义异步函数里也能发挥作用,实现中断功能。示例代码如下:

// 定义一个自定义异步函数,接收一个信号对象作为参数
function customAsyncFunction(signal) {
  return new Promise((resolve, reject) => {
    // 使用setInterval模拟异步操作,每1秒执行一次
    const intervalId = setInterval(() => {
      console.log(\'异步操作正在执行...\');
      // 检查信号对象的aborted属性,如果为true,表示操作被取消
      if (signal.aborted) {
        // 清除定时器,停止异步操作
        clearInterval(intervalId);
        // 抛出一个带有错误信息的DOMException,标记操作已被取消
        reject(new DOMException(\'操作已被取消\', \'AbortError\'));
      }
    }, 1000);
  });
}

// 创建AbortController实例和信号对象
const controller = new AbortController();
const signal = controller.signal;

// 调用自定义异步函数,并传入信号对象
customAsyncFunction(signal)
  .then(() => console.log(\'异步操作完成\'))
  .catch(error => {
    // 处理错误,判断是否是因为操作被取消导致的错误
    if (error.name === \'AbortError\') {
      console.log(\'异步操作已被取消\');
    } else {
      // 其他错误,打印错误信息
      console.error(\'异步操作出错:\', error);
    }
  });

// 延迟3秒后,调用abort方法取消异步操作
setTimeout(() => {
  controller.abort();
}, 3000);

在这个示例中,customAsyncFunction函数内部会根据传入的信号对象状态来决定是否停止异步操作。通过setTimeout延迟3秒后调用controller.abort(),就能中断这个自定义的异步函数。

(一)使用变量控制异步函数中断

除了AbortController,我们还可以用一个变量来控制自定义异步函数的中断,这种方式比较基础和直观。代码示例如下:

// 定义一个自定义异步函数
function customAsyncFunction() {
    // 定义一个变量,用于标记异步操作是否被取消
    let isAborted = false;

    return {
        // 返回一个Promise对象,在Promise内部模拟异步操作
        promise: new Promise((resolve, reject) => {
            // 使用setInterval模拟异步操作,每1秒执行一次
            const intervalId = setInterval(() => {
                console.log(\'异步操作正在执行...\');
                // 如果isAborted为true,说明操作被取消
                if (isAborted) {
                    // 清除定时器,停止异步操作
                    clearInterval(intervalId);
                    // 抛出错误,标记操作已被取消
                    reject(new Error(\'操作已被取消\'));
                }
            }, 1000);
        }),
        // 定义一个abort方法,用于设置isAborted为true,取消异步操作
        abort: () => {
            isAborted = true;
        }
    };
}

// 调用自定义异步函数,获取包含Promise和abort方法的对象
const asyncTask = customAsyncFunction();

// 处理异步操作的结果或错误
asyncTask.promise
   .then(() => console.log(\'异步操作完成\'))
   .catch(error => {
        console.error(\'异步操作出错:\', error.message);
    });

// 延迟3秒后,调用abort方法取消异步操作
setTimeout(() => {
    asyncTask.abort();
}, 3000);

在这段代码里,customAsyncFunction返回一个包含Promiseabort方法的对象。abort方法可以改变isAborted变量的值,从而中断异步操作。

(二)使用变量控制和AbortController对比

  1. 使用变量控制的优缺点
    • 优点:这种方式简单直接,不需要学习新的API,对于小型项目或者简单的异步控制场景来说,很容易理解和实现。
    • 缺点:缺乏标准化,在不同的异步函数中都要重复编写类似的控制逻辑,这使得代码的可维护性和扩展性较差。当项目规模逐渐变大,管理多个异步操作的中断状态会变得很复杂。
  2. 使用AbortController的优缺点
    • 优点AbortController是JavaScript官方标准化的API,有统一的使用方式和错误处理机制。它可以在不同的异步操作(如fetch请求、自定义异步函数等)中复用,大大增强了代码的可维护性和一致性。在与第三方库或框架集成时,和其他使用AbortController的代码交互也更方便。
    • 缺点:对于初学者而言,需要额外学习AbortController的使用方法,存在一定的学习成本。

总体来说,使用变量控制能满足基本的异步函数中断需求,但在复杂项目中,AbortController是更优雅、更值得推荐的选择。

三、利用Promise.race实现超时中断

Promise.race也可以用来实现异步操作的超时中断。下面通过代码示例来看看具体怎么做:

// 定义一个异步操作函数,模拟一个需要5秒才能完成的任务
function asyncOperation() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(\'操作完成\');
    }, 5000);
  });
}

// 定义一个超时函数,在指定时间后抛出错误
function timeout(ms) {
  return new Promise((_, reject) => {
    setTimeout(() => {
      reject(new Error(\'操作超时\'));
    }, ms);
  });
}

// 使用Promise.race,同时执行异步操作和超时判断
Promise.race([asyncOperation(), timeout(3000)])
  .then(result => console.log(result))
  .catch(error => console.error(error.message));

在这段代码中,Promise.race会同时执行asyncOperationtimeout这两个Promise。如果timeout先完成(即3秒内asyncOperation没有完成),就会触发catch块,提示操作超时;如果asyncOperation在3秒内完成,就会执行then块,打印操作完成的结果。

通过上述这些方法,我们可以在不同的场景下,优雅地中断正在执行的JavaScript异步函数,提升程序的灵活性和用户体验。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/6855.html

管理员

相关推荐
2025-08-06

文章目录 一、Promise基础回顾 二、Promise 与 axios 结合使用场景及方法 (一)直接返回 axios …

269
2025-08-06

文章目录 一、模块初始化时的内部机制 二、常见导出写法的差异分析 (一)写法一:module.exports…

107
2025-08-06

文章目录 一、ResizeObserver详解 (一)ResizeObserver是什么 (二)ResizeObserver的基本用法 …

683
2025-08-06

文章目录 一、前期准备工作 (一)下载相关文件 (二)安装必要工具 二、处理扣子空间生成的文件…

338
2025-08-06

文章目录 一、官方文档 二、自动解包的数据类型 ref对象:无需.value即可访问 reactive对象:保持…

371
2025-08-06

文章目录 一、Hooks的工作原理 二、在if语句中使用Hook会出什么岔子? 三、React官方的Hook使用规…

843
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号