当前第2页 返回上一页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | {
let abortController = null ;
document.querySelector( '#calculate' ).addEventListener( 'click' ,async ( { target } )=>{
if ( abortController ) {
abortController.abort();
abortController = null ;
target.innerText = 'Calculate' ;
return ;
}
abortController = new AbortController();
target.innerText = 'Stop calculation' ;
try {
const result = await calculate( abortController.signal );
alert( result );
} catch {
alert( 'WHY DID YOU DO THAT?!' );
} finally {
abortController = null ;
target.innerText = 'Calculate' ;
}
} );
function calculate( abortSignal ) {
return new Promise( ( resolve, reject ) => {
const timeout = setTimeout( ()=> {
resolve( 1 );
}, 5000 );
abortSignal.addEventListener( 'abort' , () => {
const error = new DOMException(
'Calculation aborted by the user' , 'AbortError'
);
clearTimeout( timeout );
reject( error );
} );
} );
}
}
|
如你所见,代码变得更长了。但是没有理由惊慌,它并没有变得更难理解!
一切都包含在块(1)中,该块相当于IIFE。因此,abortController
变量(2)不会泄漏到全局作用域内。
首先,将其值设置为 null
。鼠标单击按钮时,此值会更改。然后将其值设置为 AbortController
的新实例(3)。之后,将实例的 signal
属性直接传递给你的 calculate()
函数(4)。
如果用户在五秒钟之内再次单击该按钮,则将导致调用 abortController.abort()
函数(5)。反过来,这将在你先前传递给 calculate()
的 AbortSignal
实例上触发 abort
事件(6)。
在 abort
事件侦听器内部,删除了滴答计时器(7)并拒绝了带有适当错误的promise (8; 根据规范 ,它必须是类型为 'AbortError'
的 DOMException
)。该错误最终把控制权传递给 catch
(9)和 finally
块(10)。
你还应该准备处理如下情况的代码:
1 2 3 4 | const abortController = new AbortController();
abortController.abort();
calculate( abortController.signal );
|
在这种情况下,abort
事件将不会被触发,因为它发生在将信号传递给 calculate()
函数之前。因此你应该进行一些重构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function calculate( abortSignal ) {
return new Promise( ( resolve, reject ) => {
const error = new DOMException(
'Calculation aborted by the user' , 'AbortError'
);
if ( abortSignal.aborted ) {
return reject( error );
}
const timeout = setTimeout( ()=> {
resolve( 1 );
}, 5000 );
abortSignal.addEventListener( 'abort' , () => {
clearTimeout( timeout );
reject( error );
} );
} );
}
|
错误被移到顶部(1)。因此,你可以在代码不同部分中重用它(但是,创建一个错误工厂会更优雅,尽管听起来很愚蠢)。另外出现了一个保护子句,检查 abortSignal.aborted
(2)的值。如果等于 true
,那么 calculate()
函数将会拒绝带有适当错误的 promise,而无需执行任何其他操作。
这就是创建完全可中止的异步函数的方式。 演示可在这里获得(https://blog.comandeer.pl/ass...)。请享用!
英文原文地址:https://ckeditor.com/blog/Aborting-a-signal-how-to-cancel-an-asynchronous-task-in-JavaScript/
相关教程推荐:JavaScript视频教程
以上就是如何取消JavaScript中的异步任务?的详细内容,更多文章请关注木庄网络博客!
返回前面的内容
相关阅读 >>
javascript中的垃圾回收和内存泄漏
什么是javascript引擎
javascript是一门什么脚本语言
typescript和javascript有什么区别
js怎样直接操作二进制数据
javascript怎么改变文本内容
介绍javascript正则实现表达式以字母开头
jscript和javascript的区别是什么
javascript如何定义方法
聊聊typescript中enum(枚举)的用法
更多相关阅读请进入《javascript》频道 >>
人民邮电出版社
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者
转载请注明出处:木庄网络博客 » 如何取消JavaScript中的异步任务?