当前位置: 首页 > 面试题库 >

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

周鸿云
2023-03-14
问题内容

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

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

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

但是,一旦从缓存中检索Promise#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中获得应用。他们
不错的提前输入。



 类似资料:
  • 问题内容: 关于这两个重要来源:NZakas- 承诺链中的归还承诺 和MDN承诺,我想提出以下问题: 每次我们从承诺履行处理程序返回值时,该值如何传递给从同一处理程序返回的新承诺? 例如, 在这个例子中,是一个承诺。也是来自履行处理程序的承诺。但是。取而代之的是神奇地解决(如何?),然后将该值传递给的实现处理程序。即使是这里的句子也令人困惑。 您能给我解释一下这到底是怎么回事吗?我对这个概念感到困

  • 问题内容: AngularJS文档说: $ qpromise由模板引擎以角度识别,这意味着在模板中,您可以将附加到作用域的promise视为它们的结果值。 所以有人可以解释一下这种提琴无法正常工作的原因吗?不可能更改文本字段的值。但是分配保证$http服务返回作用域字段的工作就像一个超级按钮。 控制器: HTML: 问题答案: 您需要在promise对象上使用then()函数: 就您而言,我认为您

  • Promises是一种在JavaScript中实现异步编程的简洁方法(ES6新功能)。 在承诺之前,Callbacks用于实现异步编程。 让我们首先了解异步编程及其实现,使用Callbacks。 了解回调 函数可以作为参数传递给另一个函数。 这种机制被称为Callback 。 回调对事件有帮助。 以下示例将帮助我们更好地理解这一概念。 <script> function notifyA

  • 问题内容: 使用诺言时,如何正确地退出取消按钮而不会引发错误?我的代码会发出带有所需复选框的警报确认。该代码按应对用户执行的方式执行,但会在控制台窗口中引发错误: 没抓住(承诺)取消 问题答案: 更新(2017年1月): 此问题已在v7中修复:v7升级指南↗ 您需要向Promise添加拒绝处理程序。另外,您可以使用一种快速的方法来简单地排除错误: PS。您使用的软件包称为SweetAlert 2

  • 问题内容: 我使用mbostock / queue 来排队一些异步操作。不仅要进行速率限制(UI生成的事件很少,后端可以缓慢地处理该事件),而且还要确保依次处理它们。我用它像 我已经使用angular.js $ q进行异步操作了。所以,我必须使用,还是可以建立一个队列(这本来就是https://github.com/kriskowal/q) 谢谢。 问题答案: 基本$ q链示例 是的,您 可以 使

  • 问题内容: 我对诺言不太熟悉。我想从承诺电话中隐藏承诺的实现。 例: 然后我将在同一文件中而不是在同一函数中解决我的诺言,我称其为诺言。 现在,我知道“ promiseFriend”是不确定的。我如何才能将承诺电话与承诺解决方案区分开? 问题答案: 如果要在函数中定义一个promise并在其他地方使用它,则首先需要从该函数返回promise,而您在代码中没有这样做。然后,您需要实际调用您也没有执行