如何取消JavaScript中的异步任务?


本文摘自PHP中文网,作者青灯夜游,侵删。

有时候执行异步任务可能是很困难的,尤其是在特定的编程语言不允许取消被错误启动或不再需要的操作时。幸运的是 JavaScript 提供了非常方便的功能来中止异步活动。在本文中,你可以学到如何创建可中止的函数。

中止信号(Abort signal)

在将 Promise 引入 ES2015 并出现了一些支持新异步解决方案的 Web API 之后不久,需要取消异步任务的需求就出现了。最初的尝试集中在创建通用解决方案上,并期待以后可以成为 ECMAScript 标准的一部分。但是,讨论很快陷入僵局,无法解决问题。因此,WHATWG 准备了自己的解决方案,并以 AbortController 的形式将其直接引入 DOM。这种解决方案的明显缺点是 Node.js 中不提供 AbortController,从而在该环境没有任何优雅或官方的方式来取消异步任务。

正如你在 DOM 规范中所看到的,AbortController 是用一种非常通用的方式描述的。所以你可以在任何类型的异步 API 中使用 ―― 甚至是那些目前还不存在的 API。目前只有 Fetch API 正式支持,但是你也可以在自己的代码中使用它!

在开始之前,让我们花点时间分析一下 AbortController 的工作原理:

1

2

3

4

5

6

7

8

9

10

const abortController = new AbortController(); // 1

const abortSignal = abortController.signal; // 2

 

fetch( 'http://example.com', {

    signal: abortSignal // 3

} ).catch( ( { message } ) => { // 5

    console.log( message );

} );

 

abortController.abort(); // 4

查看上面的代码,你会发现在开始时创建了 AbortController DOM 接口的新实例(1),并将其 signal 属性绑定到变量(2)。然后调用 fetch() 并传递 signal 作为其选项之一(3)。要中止获取资源,你只需调用abortController.abort()(4)。它将自动拒绝 fetch()的 promise,并且控件将传递给 catch()块(5)。

signal 属性本身非常有趣,它是该节目的主要明星。该属性是 AbortSignal DOM 接口的实例,该实例具有 aborted 属性,其中包含有关用户是否已调用 abortController.abort() 方法的信息。你还可以将 abort 事件侦听器绑定到将要调用 abortController.abort() 时调用的事件监听器。换句话说:AbortController 只是 AbortSignal 的公共接口。

可终止函数

假设我们用一个异步函数执行一些非常复杂的计算(例如,异步处理来自大数组的数据)。为简单起见,示例函数通过先等待五秒钟然后再返回结果来模拟这一工作:

1

2

3

4

5

6

7

8

9

10

11

function calculate() {

  return new Promise( ( resolve, reject ) => {

    setTimeout( ()=> {

      resolve( 1 );

    }, 5000 );

  } );

}

 

calculate().then( ( result ) => {

  console.log( result );

} );

但有时用户希望能够中止这种代价高昂的操作。没错,他们应该有这样的能力。添加一个能够启动和停止计算的按钮:

Calculate" title="" data-original-title="复制">

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<button id="calculate">Calculate</button>

 

<script type="module">

document.querySelector('#calculate').addEventListener('click',async({ target })=>{//1

    target.innerText = 'Stop calculation';

 

    const result = await calculate(); // 2

 

    alert( result ); // 3

 

    target.innerText = 'Calculate';

  } );

 

  function calculate() {

    return new Promise( ( resolve, reject ) => {

      setTimeout( ()=> {

        resolve( 1 );

      }, 5000 );

    } );

  }

</script>

在上面的代码中,向按钮(1)添加一个异步 click 事件侦听器,并在其中调用 calculate() 函数(2)。五秒钟后,将显示带有结果的警报对话框(3)。另外, script [type = module] 用于强制 JavaScript 代码进入严格模式――因为它比 'use strict' 编译指示更为优雅。

现在添加中止异步任务的功能:

阅读剩余部分

相关阅读 >>

javascript的exec方法怎么用

聊聊javascript中实现抽离公共函数的方法

一起了解js中的深拷贝与浅拷贝

html5实现微信jssdk录音播放语音的实例

electron页内查找模块介绍(代码示例)

bootstrap请求javascript失败是怎么回事

javascript怎么设置图片大小

理解javascript中的closure(闭包)

javascript基于什么的语言

es6 map原理分析

更多相关阅读请进入《javascript》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...