当前位置: 首页 > 知识库问答 >
问题:

promise--有可能强制取消promise吗

鱼宜
2023-03-14

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

基本上,这个场景是这样的,我在UI上有一个预先输入的搜索,其中请求被委托给后端,必须根据部分输入执行搜索。虽然这个网络请求(#1)可能需要一点时间,但用户继续键入,最终触发另一个后端调用(#2)

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

但是,一旦从缓存中检索到Promission#1,我如何取消它呢?

有人能提出一个方法吗?

共有2个答案

董哲
2023-03-14

关于可撤销承诺的标准建议已经失败。

承诺不是实现承诺的异步操作的控制面;混淆了所有者和消费者。相反,创建可以通过一些传入令牌取消的异步函数。

另一个promise是一个很好的标记,使cancel易于用promissione.race实现:

示例:使用promise.race取消前一个链的效果:

null

let cancel = () => {};

input.oninput = function(ev) {
  let term = ev.target.value;
  console.log(`searching for "${term}"`);
  cancel();
  let p = new Promise(resolve => cancel = resolve);
  Promise.race([p, getSearchResults(term)]).then(results => {
    if (results) {
      console.log(`results for "${term}"`,results);
    }
  });
}

function getSearchResults(term) {
  return new Promise(resolve => {
    let timeout = 100 + Math.floor(Math.random() * 1900);
    setTimeout(() => resolve([term.toLowerCase(), term.toUpperCase()]), timeout);
  });
}
Search: <input id="input">
解飞语
2023-03-14

ES6承诺暂不支持取消。它已经在路上了,它的设计是很多人努力工作的。声音消除语义是很难得到正确的,这是正在进行的工作。有有趣的辩论“取”回购,在esselve和其他几个回购在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();

对于令牌方法来说,这并不是太难:

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这样的库在这里并不“闪耀”,因为它们是可观察的库,它们只是拥有用户级promise库一样的优势,不受规范约束。我想我们会等到ES2016年的时候再来看看可观测到的东西会变成原生的。他们是漂亮的打字机,虽然。

 类似资料:
  • 本文向大家介绍如何取消promise?相关面试题,主要包含被问及如何取消promise?时的应答技巧和注意事项,需要的朋友参考一下 Promise/A+标准规定了:原Promise对象跟新返回的对象状态一致。所以可以通过返回一个始终是pending状态的Promise对象来取消Promise。 Promise.resolve().then(() => { console.log(1) return

  • 问题内容: 是否有清除JavaScript 实例的方法? 我已经在QUnit之上编写了一个JavaScript测试框架。该框架通过在.NET中运行每个测试来同步运行测试。(很抱歉,此代码块的长度。我已尽我所能对其进行了评论,因此它不会那么乏味。) 如果测试超时,我的超时Promise将会在测试中进行测试,以便将测试标记为失败,这一切都很好,但是测试继续运行,因为测试Promise()仍在等待解决它

  • 是否有一种方法/pattern来实现? promise-数组包含构造和返回promise的函数 应在所有解析后解析 只有promise应并行运行 第n+1个promise应在n个完成后立即开始。以便始终有解析器并行运行。

  • Promise的限制 本节中我们将要讨论的许多细节已经在这一章中被提及了,但我们将明确地复习这些限制。 顺序的错误处理 我们在本章前面的部分详细讲解了Promise风格的错误处理。Promise的设计方式——特别是他们如何链接——所产生的限制,创建了一个非常容易掉进去的陷阱,Promise链中的错误会被意外地无声地忽略掉。 但关于Promise的错误还有一些其他事情要考虑。因为Promise链只不

  • 鉴于以下情况 只会包含第一个被拒绝的promise。有没有办法抓住所有被拒绝的promise?

  • 如果我不想使用自动通信模式,sping提供了另一种方法。 spring kafkfa/#提交补偿为我们提供了以下关于提交补偿的信息: -当侦听器在处理记录后返回时提交偏移量 -处理poll()返回的所有记录后提交偏移量 -当poll()返回的所有记录都已被处理时,只要超过自上次提交以来的确认时间,就提交偏移量 -当poll()返回的所有记录都已被处理时,只要自上次提交以来已收到ackCount记录