站长网_站长创业_站长主页_站长之家_易采站长站

会员投稿 投稿指南 站长资讯通告: JS实现网页时钟特效
搜索:
您的位置: 主页 > 教程 > 网页编程 > JavaScript > » 正文

如何优雅地取消 JavaScript 异步任务

来源: 易采站长站

在程序中处理异步任务通常比较麻烦,尤其是那些不支持取消异步任务的编程语言。所幸的是,JavaScript 提供了一种非常方便的机制来取消异步任务。

中断信号

自从 ES2015 引入了  Promise ,开发者有了取消异步任务的需求,随后推出的一些 Web API 也开始支持异步方案,比如 Fetch API。TC39 委员会(就是制定 ECMAScript 标准的组织)最初尝试定义一套通用的解决方案,以便后续作为 ECMAScript 标准。但是后来讨论不出什么结果来,这个问题也就搁置了。鉴于此,WHATWG (HTML 标准制定组织)另起炉灶,自己搞出一套解决方案,直接在 DOM 标准上引入了 AbortController。这种做法的坏处显而易见,因为它不是语言层面的 ECMAScript 标准,因此 Node.js 平台也就不支持  AbortController 

在 DOM  规范里, AbortController 设计得非常通用,因此事实上你可以用在任何异步 API 中。目前只得到 Fetch API 的官方支持,但你完全可以用在自己的异步代码里。

在开始介绍之前,我们先看下 AbortController 的工作原理:

const abortController = new AbortController(); // 1
const abortSignal = abortController.signal; // 2

fetch( 'http://kaysonli.com', {
 signal: abortSignal // 3
} ).catch( ( { message } ) => { // 5
 console.log( message );
} );

abortController.abort(); // 4

上面的代码很简单,首先创建了AbortController的一个实例(1),并将它的 signal 属性赋值给一个变量(2)。然后调用fetch()并传入 signal 参数(3)。取消请求时调用 abortController.abort()(4)。这样就会自动执行fetch() 的 reject ,也就是进入catch()部分(5)。

它的signal属性是核心所在。该属性是 AbortSignal DOM 接口的实例,它有一个 aborted属性,带有是否调用了 abortController.abort()的相关信息。还可以在上面监听abort事件,该事件在abortController.abort()调用时触发。简单来说,AbortController 就是AbortSignal的一个公开接口。

可取消的函数

假设有一个执行复杂计算的异步函数,为简单起见,我们就用定时器模拟:

function calculate() {
 return new Promise( ( resolve, reject ) => {
  setTimeout( ()=> {
   resolve( 1 );
  }, 5000 );
 } );
}

calculate().then( ( result ) => {
 console.log( result );
} );

可能的情况是,用户想取消这种耗时的任务。我们用一个按钮来开始和停止:

<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 2 3 4 5 6
易采站长站 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助 -