取消承诺



用户可以通过在UI中输入值来进行异步调用。

当用户更改UI中的值时,可能在调用提供给异步调用返回的promise的回调之前,会进行另一个异步调用。

正在使用的异步API返回基于Q的承诺。

如何优雅地取消原始调用,确保即使系统返回第一个调用的值,promise的.then部分也不会使用该值调用(但最终会在第二个异步调用完成时调用)?

以前我遇到过这样的情况(node.js),我要么在做web请求,要么在做db请求。我有一个超时对象,我认为它是可以取消的(sry,不记得细节了),并且对它们都有承诺。因此,如果网页首先返回,我会取消超时并返回html。如果首先发生超时,我会将JSON中的"timedout"字段更新为yes,这样,如果web调用返回,它就会知道死亡。这有点令人震惊,因为有了这些承诺,我可以进入功能一次,实际上可以返回两次!

希望能帮助

-Tom

如果没有取消API,每个异步调用都将运行到完成,但如果您只想取消.then()函数,那么这是可行的。最直接的方法是计数器:

var counter = 0;
function onClick() {
  counter++;
  doAsyncCall().then(function(result) {
    if (!--counter) {
      myFunc(result);
    }
  });
}

但你要求优雅,所以也许一个更可重复使用的结构是这样的:

var idle;
function onClick(){
  idle = Overtake(idle, doAsyncCall());
  idle.then(myFunc).then(myOtherFunc);
}

可以这样实现:

function Overtaker(prior, callp) {
  if (prior) {
    prior.cancel();
  }
  var p;
  p = new Promise(function(resolve, reject) {
    callp.then(function(value)  { return p && resolve(value); },
               function(reason) { return p && reject(reason); });
  });
  this.cancel = function() { p = null; }
  this.then = function(onFulfilled, onRejected) {
    return p.then(onFulfilled, onRejected);
  }
}
function Overtake(prior, p) {
  return new Overtaker(prior, p);
}

我使用的是ES6 promise,但Q promise看起来很相似,所以希望它也能在那里工作。

相关内容

  • 没有找到相关文章

最新更新