javascript - 中止 ecmascript7 异步函数

标签 javascript promise es6-promise cancellation ecmascript-next

有没有办法取消 ES7 异步函数?

在此示例中,在单击时,我想在调用新函数之前中止异步函数调用。

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 中还没有内置任何内容,但您可以轻松地自己动手。

MS.Net 使用取消 token 的概念来取消任务(Promises 的 .net 等价物)。它工作得很好,所以这是 JavaScript 的简化版本。

假设您制作了一个旨在表示取消的类:

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

然后您更新了您的 sleep 函数以了解此标记:

function delayAsync(timeMs, cancellationToken){
  return new Promise((resolve, reject) => {
    setTimeout(resolve, timeMs);
    if(cancellationToken)
    {
      cancellationToken.register(reject);
    }
  });
}

现在您可以使用 token 取消传递给它的异步函数:

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/await 风格做或多或少相同的事情:

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)

关于javascript - 中止 ecmascript7 异步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32897385/

相关文章:

javascript - 更改 php 文件时,语义 UI 自动建议搜索栏不会在 Firefox 中加载结果(返回相同的语法)

javascript - 基于Eval图启动脚本

javascript - 等待 fs.promises 列表

javascript - 使用 $.when 时如何解决竞争条件

Javascript Promise 和 Firebase

javascript - 当 Promise 状态被拒绝或解决时

Javascript IMAP 和 SMTP 客户端?

JavaScript 全局设置

javascript - 如何将 Promises 与 if 结合起来?

javascript - 如何等到整批请求发出并且 promise 得到解决后,才在回调函数上发送数据?