JavaScript中实现中断异步函数的几种方法

JavaScript中实现中断异步函数的几种方法

文章目录

一、借助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返回一个包含Promise和abort方法的对象。abort方法可以改变isAborted变量的值,从而中断异步操作。

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

使用变量控制的优缺点

优点:这种方式简单直接,不需要学习新的API,对于小型项目或者简单的异步控制场景来说,很容易理解和实现。

缺点:缺乏标准化,在不同的异步函数中都要重复编写类似的控制逻辑,这使得代码的可维护性和扩展性较差。当项目规模逐渐变大,管理多个异步操作的中断状态会变得很复杂。

使用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会同时执行asyncOperation和timeout这两个Promise。如果timeout先完成(即3秒内asyncOperation没有完成),就会触发catch块,提示操作超时;如果asyncOperation在3秒内完成,就会执行then块,打印操作完成的结果。

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

版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。本文链接:https://www.panziye.com/front/16422.html

喜欢 (0)赏【请潘老师喝杯Coffee吧!】分享 (0)

相关文章

“世界杯决赛去哪儿看?来这~”
神器365软件下载

“世界杯决赛去哪儿看?来这~”

⌛ 07-17 👁️‍🗨️ 5525
qq飞车手游离婚条件及步骤详解
365bet官网网址多少

qq飞车手游离婚条件及步骤详解

⌛ 07-04 👁️‍🗨️ 7071
获取新币方法推荐 明日之后交易币怎么刷
365bet官网网址多少

获取新币方法推荐 明日之后交易币怎么刷

⌛ 07-11 👁️‍🗨️ 2946
Smartisan 手机如何截图?
神器365软件下载

Smartisan 手机如何截图?

⌛ 07-02 👁️‍🗨️ 3176
京剧中黑色脸谱代表着什么?
365bet官网网址多少

京剧中黑色脸谱代表着什么?

⌛ 07-16 👁️‍🗨️ 5674
《白月梵星》梵樾身份揭秘:前世今生的禁忌恋情
365bet官网网址多少

《白月梵星》梵樾身份揭秘:前世今生的禁忌恋情

⌛ 07-12 👁️‍🗨️ 5931