中止ecmascript7异步功能 [英] Abort ecmascript7 async function

查看:73
本文介绍了中止ecmascript7异步功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以取消ES7异步功能?

Is there a way to cancel a ES7 async function?

在此示例中,单击时,我想在调用new之前中止异步功能调用。

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();
});


推荐答案

JavaScript尚未内置任何功能,但是您可以

There's nothing built in to JavaScript yet, but you could easily roll your own.

MS.Net使用取消令牌的概念来取消任务(相当于Promises的.net)。效果很好,因此这是JavaScript的简化版本。

MS.Net uses the concept of a cancellation token for the cancelling of Tasks (the .net 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

...或使用async /或多或少地做同一件事而是等待方式:

...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)

这篇关于中止ecmascript7异步功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆