有没有办法终结一条可行的链条?

时间:2018-09-26 04:46:52

标签: 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
})

有没有办法结束一条可循环的链条?

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

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

2 个答案:

答案 0 :(得分:1)

您的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反模式的一些解释

标记的1st anti-patterntry..catch中不必要的嵌套then块有关。在其中,您可以同步返回(甚至undefined),另一个Promise(都为thenable)或抛出错误(将被catch捕获)。基本上,您不需要显式捕获它,而让它“流过”。

上面提到的2nd anti-pattern是一个事实,在大多数使用情况下,第二个参数-then的拒绝处理程序被认为是次优的。一个Promise链应该利用一个catch来简化工作流程。

但是,在极少数需要执行“早期捕获”和“恢复”的情况下,请考虑以下方法,该方法仍然比对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
})

答案 1 :(得分:0)

简短的回答是“否”,没有机制可以在then处理程序中终止链的一半。 (在2016年向TC39委员会提出了取消承诺的提案,但后来被撤回了。)

请注意,“承诺链” 通常是指承诺 在串联在一起的单个promise方法调用链中,由最后thencatchfinally调用返回。

当执行定义链的代码时,对上面列出的promise方法的所有调用都是同步进行的。执行后,将创建链中的所有promise,并调用链中的所有方法调用。

由于promise只有三种状态(未决,已实现和已拒绝),因此您最好的办法是安排“取消”在链接的promise的拒绝通道中发送,并根据需要忽略它。 (没有标准的“已取消”拒绝值可以使用)。