Javascript 取消承诺

Javascript 取消承诺,javascript,promise,q,cancellation,Javascript,Promise,Q,Cancellation,用户可以通过在UI中输入值进行异步调用 当用户更改UI中的值时,会进行另一个异步调用—可能是在调用提供给异步调用返回的承诺的回调之前 正在使用的异步API返回一个基于Q的承诺 我如何才能优雅地取消最初的调用,确保即使系统返回第一个调用的值,承诺的。然后部分也不会使用该值调用(但在第二个异步调用完成时它最终会被调用)?早在我遇到这样的情况时(node.js)我在做一个web或db请求。我有一个超时对象,我认为它是可取消的(sry,不记得细节),并且对它们都有承诺。因此,如果网页首先返回,我会取消超

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

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

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


我如何才能优雅地取消最初的调用,确保即使系统返回第一个调用的值,承诺的
。然后
部分也不会使用该值调用(但在第二个异步调用完成时它最终会被调用)?

早在我遇到这样的情况时(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);
}
可以这样实现:

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承诺,但Q承诺看起来很相似,所以希望它也能在那里起作用。

我看不到承诺原型上的拒绝。承诺的消费者不能修改它-只能修改延迟的承诺。好吧,我有一个基本的误解。作为返回承诺的API的客户端,我是否可以取消对提供给承诺的
then
方法的回调的调用?@Ben monkey修补请求承诺或使用支持取消的库。@Ben还-如果使用支持取消的库,则可以。