admin管理员组文章数量:1400329
Is there a way to cancel a ES7 async function?
In this example, on click, I want to abort async function call before calling new.
async function draw(){
for(;;){
drawRandomRectOnCanvas();
await sleep(100);
}
}
function sleep(t){
return new Promise(cb=>setTimeout(cb,t));
}
let asyncCall;
window.addEventListener('click', function(){
if(asyncCall)
asyncCall.abort(); // this dont works
clearCanvas();
asyncCall = draw();
});
Is there a way to cancel a ES7 async function?
In this example, on click, I want to abort async function call before calling new.
async function draw(){
for(;;){
drawRandomRectOnCanvas();
await sleep(100);
}
}
function sleep(t){
return new Promise(cb=>setTimeout(cb,t));
}
let asyncCall;
window.addEventListener('click', function(){
if(asyncCall)
asyncCall.abort(); // this dont works
clearCanvas();
asyncCall = draw();
});
Share
Improve this question
edited Feb 29, 2016 at 23:37
Felix Kling
818k181 gold badges1.1k silver badges1.2k bronze badges
asked Oct 1, 2015 at 21:46
YukuléléYukulélé
17.2k12 gold badges76 silver badges103 bronze badges
2
- yes @spender, of course, thank! (edited) – Yukulélé Commented Oct 1, 2015 at 21:52
- possible duplicate of How to cancel an EMCAScript6 (vanilla JavaScript) promise chain and a few others – Bergi Commented Oct 1, 2015 at 21:57
2 Answers
Reset to default 6There's nothing built in to JavaScript yet, but you could easily roll your own.
MS.Net uses the concept of a cancellation token for the cancelling of Tasks (the equivalent of Promises). It works quite nicely, so here's a cut-down version for JavaScript.
Say you made a class that is designed to represent cancellation:
function CancellationToken(parentToken){
if(!(this instanceof CancellationToken)){
return new CancellationToken(parentToken)
}
this.isCancellationRequested = false;
var cancellationPromise = new Promise(resolve => {
this.cancel = e => {
this.isCancellationReqested = true;
if(e){
resolve(e);
}
else
{
var err = new Error("cancelled");
err.cancelled = true;
resolve(err);
}
};
});
this.register = (callback) => {
cancellationPromise.then(callback);
}
this.createDependentToken = () => new CancellationToken(this);
if(parentToken && parentToken instanceof CancellationToken){
parentToken.register(this.cancel);
}
}
then you updated your sleep function to be aware of this token:
function delayAsync(timeMs, cancellationToken){
return new Promise((resolve, reject) => {
setTimeout(resolve, timeMs);
if(cancellationToken)
{
cancellationToken.register(reject);
}
});
}
Now you can use the token to cancel the async function that it was passed to:
var ct = new CancellationToken();
delayAsync(1000)
.then(ct.cancel);
delayAsync(2000, ct)
.then(() => console.log("ok"))
.catch(e => console.log(e.cancelled ? "cancelled" : "some other err"));
http://codepen.io/spender/pen/vNxEBZ
...or do more or less the same thing using async/await style instead:
async function Go(cancellationToken)
{
try{
await delayAsync(2000, cancellationToken)
console.log("ok")
}catch(e){
console.log(e.cancelled ? "cancelled" : "some other err")
}
}
var ct = new CancellationToken();
delayAsync(1000).then(ct.cancel);
Go(ct)
Unless your question is purely theoretical, I assume you are using Babel, Typescript or some other transpiler for es6-7 support and probably some polyfill for promises in legacy environments. Though it's hard to say what will bee standard in the future, there is a non-standard way to get what you want today:
- Use Typescript to get es6 features and async/await.
- Use Bluebird for promises in all environments to get sound promise cancellation support.
- Use cancelable-awaiter which makes Bluebird cancellations play nice with async/await in Typescript.
本文标签: javascriptAbort ecmascript7 async functionStack Overflow
版权声明:本文标题:javascript - Abort ecmascript7 async function - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744260242a2597678.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论