javascript - 有没有办法结束thenable链?

标签 javascript node.js promise

let textProcess = new Promise((resolve, reject) => {
    let text
    try {
        // fetch text from the internet
        text = "str"
        resolve(text)
    } catch (e) {
        reject("failed to fetch!")
    }
})

textProcess.then(data => {
    let json
    try {
        json = JSON.parse(data)
    } catch (e) {
        console.error("failed to parse!")
        // ..........i want to end the whole process here, never go ahead
    }
}, e => {
    // try to fetch text from local chache
}).then(json => {
    // work on the json obj
}, e => {
    // if failed to fetch from local too, just let it go
})

有没有办法结束thenable链?

看上面的例子,我想在解析失败的时候结束整个过程(前面是“…………”的那一行)。但实际上最后一个 then 仍然会被调用。

实现我的目标的正确而优雅的方法是什么?

最佳答案

您的 Promise 用法涉及相当多的次优模式。修复它们实际上也会导致您想要实现的目标。

textProcess.then(data => {
  // 1st anti-pattern fix
  // any error triggered here
  // also gets caught at the end catch
  return JSON.parse(data)
}).then(json => {
  // work on json obj
}).catch(e => {
  // 2nd anti-pattern fix
  // one catch for the whole thenable chain
  console.error("Failed to parse!", e)
})

通过这种方式,您可以正确利用 Javascript Promise 提供的功能,并使用一个简单的 .catch 来满足您的需求。


编辑 - 对涉及的 Promise 反模式的一些解释

标记的第一个反模式是关于then 中不必要的嵌套try..catch block 。在其中,您可以同步返回(甚至 undefined),另一个 Promise(这两个都是 thenable),或者抛出一个错误(这将被 catch 捕获)。基本上你不需要明确地捕捉它,而是让它“流过”。

提到的第二个反模式是这样的事实,即第二个参数——then 的拒绝处理程序在大多数用例中被认为是次优的。 Promise 链应该利用一个 catch 来简化工作流程。

但是,在需要执行“early catch”和“resume”的极少数情况下,请考虑以下方式,它仍然比对then 使用两个处理程序要清晰一些:

textProcess.then(data => {
  return parser1(data)
}).catch(e => {
  console.log("First parser failed")
  // for example first parser failed
  return "fallback data"
}).then(data => {
  // process received data as "fallback data"
}).catch(e => {
  // always have a "last resort" catch at the end of the workflow
})

关于javascript - 有没有办法结束thenable链?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52510113/

相关文章:

javascript - Angular 嵌套组件未使用 ngIf 渲染

node.js - 如果使用 Promise 存在对象,则 AWS 签名 url

javascript - 如何在 JavaScript 中使用 Promise

javascript - 具有历史实现和主题标签功能的 ajax 页面加载内容

javascript - Javascript 中的阻塞队列

javascript - 禁用浏览器快捷键

typescript - 使用 Promises 的类型 '{}' 上不存在属性

javascript - 使消息返回所有数据库行

javascript - 在node.js ES6中,是否可以传入一个类型然后实例化它?

node.js - Docker 内部的 bcrypt 警告