Promise - 是否可以强制取消 Promise

2024-01-01

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

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

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

但是,当我从缓存中检索到 Promise #1 后,如何取消它呢?

有人能建议一种方法吗?


在现代 JavaScript 中 - 不

承诺已经解决(哈),而且似乎永远不可能取消(待定)承诺。

相反,有一个跨平台(节点、浏览器等)取消原语,作为 WHATWG(也构建 HTML 的标准机构)的一部分,称为AbortController。您可以使用它来取消功能返回承诺而不是承诺本身:

// Take a signal parameter in the function that needs cancellation
async function somethingIWantToCancel({ signal } = {}) {
  // either pass it directly to APIs that support it
  // (fetch and most Node APIs do)
  const response = await fetch('.../', { signal });
  // return response.json;

  // or if the API does not already support it -
  // manually adapt your code to support signals:
  const onAbort = (e) => {
    // run any code relating to aborting here
  };
  signal.addEventListener('abort', onAbort, { once: true });
  // and be sure to clean it up when the action you are performing
  // is finished to avoid a leak
  // ... sometime later ...
  signal.removeEventListener('abort', onAbort);
}

// Usage
const ac = new AbortController();
setTimeout(() => ac.abort(), 1000); // give it a 1s timeout
try {
  await somethingIWantToCancel({ signal: ac.signal });
} catch (e) {
  if (e.name === 'AbortError') {
    // deal with cancellation in caller, or ignore
  } else {
    throw e; // don't swallow errors :)
  }
}

不,我们还不能这么做。

ES6 Promise 不支持取消yet。它正在路上,它的设计是很多人都努力工作的。Sound取消语义很难正确,而且这项工作正在进行中。关于“fetch”存储库、esdiscuss 和 GH 上的其他几个存储库存在有趣的争论,但如果我是你,我会耐心等待。

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

是的,事实是取消是really客户端编程中的一个重要场景。您所描述的情况(例如中止网络请求)很重要,而且无处不在。

所以……语言把我搞砸了!

是的,对此感到抱歉。在指定进一步的事情之前,必须先承诺 - 所以他们没有一些有用的东西,比如.finally and .cancel- 不过,它正在通过 DOM 达到规范。取消是not事后想来,这只是时间限制和 API 设计的迭代方法。

那我能做什么呢?

您有多种选择:

  • 使用第三方库,例如bluebird https://github.com/petkaantonov/bluebird他们的行动速度比规范快得多,因此可以取消以及其他一些好处 - 这就是像 WhatsApp 这样的大公司所做的事情。
  • 通过取消token.

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

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 中可观察对象何时原生化。他们are不过对于提前输入来说很漂亮。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Promise - 是否可以强制取消 Promise 的相关文章

  • 如何检测被覆盖的 CSS 属性?

    I can get all css properties for an element with document stylesheets but some of those are not active because those pro
  • 在 JavaScript 函数中加载图像

    我有获取图像像素颜色的功能 function getImage imgsrc var img img src imgsrc var imageMap new Object img load function var canvas
  • HTML 和 标签有什么区别?

    HEAD 标签和 BODY 标签有什么区别 大多数 HTML 书籍仅 简短 提及 and 标签 但它们消失得很快 它们会影响浏览器呈现网页的方式吗 另外 它们会影响 javascript 的运行顺序吗 我的意思是 如果我里面有一个javas
  • 返回上一页

    我正在使用表格来 评价 页面 此表单将数据 发布 到其他地方的 php 脚本 我只是想在处理表单后显示一个链接 这将使用户返回到上一页 我可以在 php 脚本中使用 javascript 来执行此操作吗 GF 您可以使用链接来调用histo
  • Chrome 开发工具命中代码但未命中断点

    我在 chrome 开发工具上启用了断点 并且在一行上有一个断点 我知道 chrome 正在运行 因为我将断点放在具有以下语句的行上 alert why is this not breaking 如果我在本地主机中找到该文件 则断点有效 断
  • 从对象中取出具有无效(NaN、空白等)值的键的最佳方法?

    我有一个供用户填写的简短搜索表单 将有多个搜索查询进入 MongoDB 该表单创建一个名为的变量searchParams可能看起来像这样 var searchParams city Springfield bedrooms 3 bathro
  • Node.js Express 4.0 中的 res.render 回调参数的用途是什么?

    目的是什么res render回调参数 在什么情况下 由于模板已被指定为第一个参数 因此人们会想要使用这样的回调参数 这是文档中的代码 send the rendered view to the client res render inde
  • 转义 \u200b(零宽度空格)和其他非法 JavaScript 字符

    我有一组 JavaScript 对象 我引导到后端模板 以在页面加载时初始化我的 Backbone js 集合 它看起来像这样 作为 Twig 模板 我遇到的问题是某些文本字段包含 u200b 零宽度空格 这会破坏
  • 为什么函数声明在不同浏览器中的处理方式不同?

    虽然我在谷歌中找不到对此的引用 但我熟悉这样一个事实 在 javascript 中 全局函数声明在执行任何代码之前都会被解释 换句话说 这工作得很好 f function f 但是 我注意到 chrome 和 firefox 对全局函数声明
  • 修改 Twitter 帖子上可编辑 Div 的内容

    我正在编写一个 chrome 扩展 它可以帮助用户在 Twitter 上输入内容 当在 twitter 上写推文时 twitter 会打开一个可编辑的 div 容器 当用户输入内容时 twitter 大概正在使用某些网络框架 会生成子 di
  • 非法使用break语句; javascript

    当这个变量达到一定数量时 我希望循环停止 但我不断收到错误 未捕获的语法错误 非法的中断语句 function loop if isPlaying jet1 draw drawAllEnemies requestAnimFrame loop
  • 函数不会等到 Promise 得到解决

    我正在开发一个简单的不和谐机器人 我正在尝试打印有关某个玩家的一些一般数据 我最近了解了 async await 并尝试将其实现到我的代码中 然而 它似乎不起作用 因为当我第一次触发此代码时 它会打印 null 但在后续触发时 它将打印正确
  • Next.js:错误:React.Children.only 期望接收单个 React 元素子元素

    我有一个名为Nav inside components目录及其代码如下所示 import Link from next link const Nav gt return div a Home a a About a div export d
  • AngularStrap 工具提示禁用我的自定义指令

    我正在尝试让 bs tooltip AngularStrap 指令与我自己的名为 checkStrength 的自定义指令一起使用 该指令检查密码的强度 单独使用这些指令中的任何一个时 它们都可以正常工作 但不能一起工作 This http
  • jQuery 中什么函数相当于 .SelectMany()?

    让我解释一下 我们知道 jQuery 中的映射函数充当 Select 如 LINQ 中 tr map function return this children first returns 20 tds 现在的问题是我们如何在 jQuery
  • 使 Bootstrap Popover 在悬停而不是单击时出现/消失

    我正在使用 Bootstrap 构建一个网站Popover http twitter github com bootstrap javascript html popovers我不知道如何使弹出窗口出现在悬停而不是单击时 我想做的就是当有人
  • 在 Nodejs 中,如何停止 FOR 循环直到 MongoDB 调用返回

    我正在研究下面的代码片段 我有一个名为 stuObjList 的 JSON 对象数组 我想循环遍历数组以查找具有特定标志集的特定 JSON 对象 然后进行数据库调用以检索更多数据 当然 FOR 循环不会等待数据库调用返回并到达 j leng
  • 将两个数字相加将它们连接起来而不是计算总和

    我将两个数字相加 但没有得到正确的值 例如 做1 2返回 12 而不是 3 我在这段代码中做错了什么 function myFunction var y document getElementById txt1 value var z do
  • 使用ExternalInterface和IE从JavaScript获取Flash中的当前URL

    我正在尝试获取 Flash 播放器当前所在的 URL 不是 swf 文件的 URL 而是浏览器指向的 URL 到目前为止我已经使用过 var st String ExternalInterface call window location
  • Chrome 调试器注入 javascript

    我有这样的好奇心 是否可以以某种方式在我的页面中注入 javascript 并执行它并调试它 正如您在控制台中所做的那样 但在控制台中您无法暂停并观察变量 是否可以调试我通过控制台输入的代码 为什么无法调试通过 XHR 接收的代码 Than

随机推荐

  • 如何删除cumulo实例?

    我在通过调用初始化accumulo时创建了一个实例累积初始化但现在我想删除该实例 并且我想创建一个新实例 任何人都可以帮忙做到这一点吗 从 HDFS 中删除 ACCUMULO HOME conf accumulo site xml 中的 i
  • AgGrid 自定义 html 拖动

    我只是在考虑更改 ag 网格组件的拖动悬停 我找不到太多关于它的信息 有人知道如何在拖动模式下更改行的样式吗 我的目标是拥有不同的动画 整行 例如材质 UI UX https material io design components li
  • 为什么带有 EL 2.2 的 JSF 2.x 允许 MethodExpression 代替 ValueExpression?

    我看到几个问题询问如何将参数传递给 JSF 方法 在 EL2 2 和 servlet 3 0 中 它允许用户将参数传递到方法调用中 一个例子 如何从渲染的 h outputText 将参数传递给方法 https stackoverflow
  • C++11 std::thread 接受带有右值参数的函数

    我有一些作业 并且我很难理解 可能 如何将参数传递给 std thread 构造函数 假设以下代码 我删除了不需要的部分 template
  • 使用.net core 3.0进行脚本动态编译和运行代码

    我想提供在 NET core 3 中编译和运行代码 Csharp 类 的可能性 以用于脚本编写 脚本 类 应从文件系统加载并注入现有 静态 程序集中 https laurentkempe com 2019 02 18 dynamically
  • Javascript 函数将印度货币数字转换为支持 paise 的单词

    还有比这更快的解决方案吗 在花了一些时间谷歌搜索和玩弄其他人的代码之后 我做了一个快速修复 可重用函数适用于最大 99 99 99 999 的数字 number2text 1234 56 将返回ONE THOUSAND TWO HUNDRE
  • handleWatchKitExtensionRequest 未响应 Watchkit 扩展中的 openParentApplication (Swift)

    我正在尝试将信息从我的 WatchKit 应用程序发送到我的主要父应用程序 据我了解 我应该能够使用openParentApplication在我的 watchkit 扩展中 该扩展将由handleWatchKitExtensionRequ
  • 将 YUV 作为字节数组导入

    我正在开发一个项目 必须对 YUV420 SP NV21 图像 从 Android 相机拍摄 应用阈值 以确定哪些像素是 黑色 哪些像素是 白色 因此 我想将其作为字节数组导入 Python 中 使用 OpenCV NumPy PIL 这样
  • 如何从 bash 脚本在 GitHub 操作上创建输出?

    我有一个 GitHub 操作 本质上是一个 bash 脚本 我的操作的 javascript 部分执行 bash 脚本 const core require actions core const exec require actions e
  • 在模型上重复纹理

    我正在创建一个小游戏 你在迷宫中 迷宫的组织方式是2D Array 描述x and z position和block type 原来如此Tile based 假设每个块都是1 m 现在我的角色是2m高 迷宫应该是4m高的 因此 如果该瓷砖上
  • SQL查询多个AND和OR不起作用

    我有一个单元格 其中包含由双管分隔的值 我正在尝试使用以下内容搜索此单元格的内容 其中 10 是要搜索的数字 10 10 10 和 10 我的查询似乎只返回 10 没有其他变化 有人可以告诉我为什么它不起作用吗 提前谢谢了 您在下面看到的
  • 为什么从 python/uwsgi 内部调用时 `node.js` 会死掉?

    从外壳这个python启动并与之通信的代码node js过程工作正常 gt from subprocess import gt js function m console log m hello world gt out err Popen
  • 更改java的.class文件而不重新编译

    有什么办法可以做到以下几点 所以我有一个project jar 文件 在其中我需要修改传递给classA class 的某些方法的字符串 例如 假设这个 classA class 有一个名为 change String a String b
  • 检查 Postgres 复合字段是否为 null/空

    With Postgres 复合类型 http www postgresql org docs 9 2 static rowtypes html您基本上可以构建一个字段 其结构被定义为另一个表 我有一个名为 recipient 的复合字段
  • 错误:Angular 解析期间出现 Http 失败

    我正在学习 Angular 我想在 HTML 页面上显示 JSON 数据 错误是 Angular 解析期间 Http 失败 我不知道为什么请告诉我我的错误并给我链接如何显示多种类型的 JSON 数据 person component htm
  • MSBuild - 设置解决方案的属性

    我们在 VS2008 中使用 NET 3 5 我有一个包含约 20 个项目的解决方案 随着应用程序的增长和添加新模块 这个数字会随着时间的推移而增长 今天我需要为每个项目设置一个属性 我必须编辑每个 csproj 文件以添加以下内容
  • 如何避免在 Visual Studio 2017 中加载 Microsoft.VisualStudio.Threading 时出现错误

    我已在仅针对 Visual Studio 2019 的版本中对 Visual Studio 包进行了更新日志 我开始使用 NuGet 包的一项更改微软VisualStudio SDK 版本 16 0 202 并删除了许多对 DLL 的单独引
  • "aaaa".StartsWith("aaa") 返回 false

    如果这不是一个错误 那么任何人都可以解释这种行为背后的原因吗 事实上 似乎每个奇数个字母都会返回 false string test aaaaaaaaaaaaaaaaaaaa Console WriteLine test StartsWit
  • php oop文件上传

    我正在研究 oop php 文件上传脚本 很简单 但不起作用 问题是什么 我学习如何使用 FILE 以及如何编写 oop 风格的代码 Thanks upload php 是
  • Promise - 是否可以强制取消 Promise

    我使用 ES6 Promises 来管理所有网络数据检索 在某些情况下我需要强制取消它们 基本上 场景是这样的 我在 UI 上进行预先输入搜索 其中请求委托给后端必须根据部分输入执行搜索 虽然此网络请求 1 可能需要一点时间 但用户继续键入