以干净的方式打破 javascript 承诺链

2024-03-03

我正在尝试将承诺串联起来,这样如果一个承诺被拒绝,链条就会断裂。我跟随一个人的线索上一个SO问题 https://stackoverflow.com/questions/20714460/break-promise-chain-and-call-a-function-based-on-the-step-in-the-chain-where-it并尝试将其应用于本机承诺,但我认为我误解了事物的工作方式。

这是我重写代码的方式:

Promise.resolve()
    .then(function() {
        return step(1)
            .then(null, function() {
                stepError(1);
            });
    })
    .then(function() {
        return step(2)
            .then(null, function() {
                stepError(2);
            });
    })
    .then(function() {
        return step(3)
            .then(null, function() {
                stepError(3);
            });
    });

function step(n) {
    console.log('Step '+n);
    return (n === 2) ? Promise.reject(n) : Promise.resolve(n);
}

function stepError(n) {
    console.log('Error '+n);
    return Promise.reject(n);
}

上述代码的输出是:

Step 1
Step 2
Error 2
Step 3
[UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): 2]

根据我的理解,步骤 2 应该打破链条,而步骤 3 不应该执行。当step(2)返回被拒绝的promise时,stepError(2)将按预期执行。但由于它返回 Promise.reject(2),所以下一个 then 中的函数不应该被执行,并且由于最后没有 catch,所以步骤 2 中被拒绝的 Promise 似乎会像预期的那样被转发,直到它退出链,因为它没有找到任何处理程序。

我在这里缺少什么?

这是一个可以使用的 JSFiddle:https://jsfiddle.net/6p4t9xyk/ https://jsfiddle.net/6p4t9xyk/


根据我的理解,第 2 步应该打破链条......

It would,但你不小心把拒绝变成了解决方案。

关于承诺的关键是每次调用then创建一个new根据以下内容解决/拒绝的承诺then回调会执行此操作,并且处理拒绝的回调会将拒绝转换为解决方案,除非故意这样做。

So here:

return step(2)
    .then(null, function() {  // This handler converts the
        stepError(2);         // rejection into a resolution
    });                       // with the value `undefined`

这样您就可以拥有补偿错误的错误处理程序。

Since stepError返回拒绝,您可以通过添加一个来继续拒绝return:

return step(2)
    .then(null, function() {
        return stepError(2);  // Added `return`
    });

...或者,完全删除该处理程序:

return step(2);

...或者你可以throw在回调中,这会自动变成拒绝。

未处理的拒绝警告是由于没有任何内容消耗来自的拒绝而引起的stepError.


这是一个返回结果的示例stepError:

Promise.resolve()
    .then(function() {
        return step(1)
            .then(null, function() {
                return stepError(1); // Added `return`
            });
    })
    .then(function() {
        return step(2)
            .then(null, function() {
                return stepError(2); // Added `return`
            });
    })
    .then(function() {
        return step(3)
            .then(null, function() {
                return stepError(3); // Added `return`
            });
    });

function step(n) {
    console.log('Step '+n);
    return (n === 2) ? Promise.reject(n) : Promise.resolve(n);
}

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

以干净的方式打破 javascript 承诺链 的相关文章

  • Ajax文件上传

    我想使用 Ajax 和 php 上传文件 我有一个表格
  • iPad - 无法在框架内滚动

    我无法滚动 iPad Safari 中框架内调用的 pdf 我已经尝试过两件事 2 指滚动 使用对象 嵌入代替框架 但这是行不通的 事实上我已经尝试了很多东西 溢出 高度等等 请帮我 先感谢您 根据这篇文章http support appl
  • 将 R (ramda) 导入 typescript .ts 文件

    我正在尝试使用Ramda js如下
  • ReactiveX:仅对每组中的最后一项进行分组和缓冲

    如何对 Observable 进行分组 并从每个 GroupedObservable 中仅将最后发出的项保留在内存中 这样每个组的行为就像BehaviorSubject 一样 像这样的东西 user 1 msg Anyone here us
  • JavaScript - 无需布尔值即可运行一次

    有没有办法只运行一段JavaScript代码ONCE 而不使用布尔标志变量来记住它是否已经运行过 具体来说not就像是 var alreadyRan false function runOnce if alreadyRan return a
  • Sonar 中的 javascript 代码覆盖率

    我是使用 Sonar 和插件进行 javascript 代码覆盖的新手 使用 Sonar 分析时 有哪些可能性可以找出 javascript 代码的质量 包括代码覆盖率 目前我正在使用 karma runner 它提供代码覆盖率报告 可以在
  • 如何强制折断不可折断的字符串?

    我有一个根据数据库中包含的数据生成的 HTML 页面 数据库有时包含浏览器无法分解的长字符串 因为这些字符串不包含可分解的字符 空格 点 逗号等 有没有办法使用 html css 甚至 javascript 来解决这个问题 看到这个link
  • Javascript 在另一个函数中检测“Shift”键按下

    我正在从 Flash 影片 使用外部接口 调用我的 html 页面中的 Javascript 函数 并且我想知道调用该函数时用户是否按下了 Shift 键 例如 如果我通过鼠标单击调用该函数 这似乎很简单 因为我可以传递事件并检查 if e
  • Angularjs 完整日历不显示事件

    我正在用那个https github com angular ui ui calendar https github com angular ui ui calendar在 Angularjs 中使用 FullCalendar 它显示日历并
  • 在动态创建的元素上添加事件监听器[重复]

    这个问题在这里已经有答案了 是否可以向所有动态生成的元素添加事件侦听器 Javascript 我不是页面的所有者 因此我无法以静态方式添加侦听器 对于页面加载时创建的所有元素 我使用 doc body addEventListener cl
  • React 应用程序中的 addEventListener 不起作用

    一些背景 我正在尝试消费自定义网络组件在 React 应用程序中并尝试监听来自 Web 组件的事件 我相信您不能只在自定义 Web 组件上以通常的反应方式处理事件 i e
  • 游戏手柄 JavaScript 未能按预期更新

    我正在尝试让浏览器报告我的 XBOX 控制器的状态 然而 在第一次按下按钮后 它似乎变得 卡住 我究竟做错了什么
  • 为什么我们使用 SpreadsheetApp.flush()?

    我的理解是 flush https developers google com apps script reference spreadsheet spreadsheet app flush有助于在功能发生时执行这些功能 而无需将它们捆绑在
  • 窗口大小调整触发的 DOM 事件

    我有一个布局相当复杂的页面 最初打开页面时 某些元素的对齐存在问题 但是 可以通过更改浏览器窗口的大小来 永久 解决此问题 显然 我不希望用户必须调整浏览器窗口的大小才能使页面正确显示 所以我想知道是否有一种方法可以在页面首次加载时以编程方
  • 根据特定字符获取整个字符串或子字符串

    我有一个包含 MIME 类型的字符串 例如application json 现在我想将其与实际的 HTTP 标头进行比较 在本例中content type 如果标头包含 MIME 类型 那么就很简单 if mimeType contentT
  • JavaScript 中的实时摩尔斯电码转换器

    在看到谷歌关于莫尔斯电码 gmail 的愚人节笑话后 我想我应该尝试用 javascript 创建一个实时莫尔斯电码转换器 我正在使用正则表达式和替换将莫尔斯电码更改为字符 例如 replace g a replace g r 我遇到的问题
  • Outlook 加载项,无法读取未定义的属性“BeginRequestEventArgs”

    我使用 Visual Studio 开发了 Outlook 插件 我的插件有一个按钮 用于填充会议邀请正文中的详细信息并添加所需的与会者 这在 99 的情况下都有效 但是 时不时地它会给我下面的 JavaScript 错误 Uncaught
  • AngularJS 在指令运行之前通过 AJAX 检索数据

    我正在使用 AngularUIuiMap http angular ui github com directives map实例化谷歌地图的指令 uiMap 指令非常适合处理硬编码数据 mapOptions and myMarkers 但是
  • ReactJs 警告:不推荐使用改变“style”。考虑事先克隆它

    我收到以下警告 inWarning div was passed a style object that has previously been mutated Mutating style is deprecated Consider c
  • 如何获得 JavaScript 阶乘程序的循环来显示所使用的工作?

    你好 我面临着用 JavaScript 编写一个程序的挑战 尽管我对它不太了解 但它要求用户输入一个数字 然后计算该数字的阶乘 我使用了已经提出的问题并设法使计算正常工作 但无法获得所需的输出 我必须在以下输出中获取它 而不使用任何花哨的库

随机推荐