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/