小编典典

承诺-是否可以强迫取消承诺

javascript

我使用ES6 Promises来管理我的所有网络数据检索,并且在某些情况下需要强制取消它们。

基本上,这种情况是这样的:我在UI上进行了预先输入搜索,在该UI中,将请求委派给后端必须基于部分输入执行搜索。尽管此网络请求(#1)可能需要一点时间,但用户继续输入,最终会触发另一个后端调用(#2)

这里#2自然优先于#1,因此我想取消Promise包装请求#1。我已经在数据层中缓存了所有Promises,因此从理论上讲,我可以在尝试提交#2的Promise时检索它。

但是,一旦从缓存中检索Promise#1,该如何取消呢?

有人可以建议一种方法吗?


阅读 406

收藏
2020-04-25

共1个答案

小编典典

不,我们还不能这样做。

ES6承诺不支持取消 还没有 。它正在进行中,其设计是很多人真正努力的工作。 声音
消除的语义很难正确理解,这正在进行中。关于“获取”回购,esdiscuss以及关于GH的其他几个回购,有一些有趣的辩论,但是如果我是你的话,请耐心等待。

但是,但是,..取消真的很重要!

事实是,取消 实际上 是客户端编程中的重要场景。您描述的情况(例如中止Web请求)非常重要,并且无处不在。

所以…语言把我搞砸了!

是的,对此感到抱歉。承诺必须得到在第一前进一步东西都规定-
所以他们就去了,没有像一些有用的东西.finally,并.cancel-这是在它的途中,虽然,通过DOM规范。取消 不是
事后的想法,它只是时间限制,是API设计的一种更迭代的方法。

那我该怎么办?

您有几种选择:

  • 使用诸如bluebird之类的第三方库,该库的运行速度可能比规范快得多,因此具有取消资格以及许多其他好处-这就是WhatsApp之类的大公司所做的。
  • 传递取消 令牌

使用第三方库很明显。至于令牌,您可以使方法接受一个函数,然后调用它,如下所示:

function getWithCancel(url, token) { // the token is for cancellation
   var xhr = new XMLHttpRequest;
   xhr.open("GET", url);
   return new Promise(function(resolve, reject) {
      xhr.onload = function() { resolve(xhr.responseText); });
      token.cancel = function() {  // SPECIFY CANCELLATION
          xhr.abort(); // abort request
          reject(new Error("Cancelled")); // reject the promise
      };
      xhr.onerror = reject;
   });
};

这会让你做:

var token = {};
var promise = getWithCancel("/someUrl", token);

// later we want to abort the promise:
token.cancel();

您的实际用例- last

使用令牌方法并不难:

function last(fn) {
    var lastToken = { cancel: function(){} }; // start with no op
    return function() {
        lastToken.cancel();
        var args = Array.prototype.slice.call(arguments);
        args.push(lastToken);
        return fn.apply(this, args);
    };
}

这会让你做:

var synced = last(getWithCancel);
synced("/url1?q=a"); // this will get canceled 
synced("/url1?q=ab"); // this will get canceled too
synced("/url1?q=abc");  // this will get canceled too
synced("/url1?q=abcd").then(function() {
    // only this will run
});

不,像Bacon和Rx这样的库在这里不会“发光”,因为它们是可观察的库,它们具有与用户级别承诺的库相同的优势,因为它们不受规范的约束。我猜我们将等到可观察性技术在ES2016中获得应用。他们
不错的提前输入。

2020-04-25