node.js - 条件承诺链
问题描述
我正在寻找将一些承诺链接在一起的代码。我有一个条件,基于一个承诺的结果,我要么调用返回承诺的下一个函数并继续链接其他几个函数,要么我什么都不做(有效地结束承诺链)。
我有以下三种可能的解决方案,但我觉得它们都有点混乱。
这是我的第一种方法,我不喜欢这里的嵌套承诺。
initalAsyncCall()
.then((shouldContinue) => {
if (shouldContinue) {
return nextStep()
.then(() => anotherStep())
}
})
.catch((error) => {
handleError(error);
})
这是我的第二个。这个似乎有点长,可能更难阅读
const shouldContinuePromise = initialAsyncCall();
const nextStepPromise = shouldContinuePromise.then((shouldContinue) => {
if (shouldContinue) return nextStep();
});
Promise.all([shouldContinuePromise, nextStepPromise])
.spread((shouldContinue) => {
if (shouldContinue) return anotherStep();
})
.catch((error) => {
handleError(error);
});
最后,这是我的最后一种方法。我在这里不喜欢的是,当它不是真正的错误时,我会抛出一个错误。
initalAsyncCall()
.then((shouldContinue) => {
if (!shouldContinue) throw new HaltException()
return nextStep();
})
.then(() => anotherStep())
.catch(HaltException, (ex) => {
// do nothing... maybe some logging
})
.catch((error) => {
handleError(error);
})
解决方案
您的第一种方法似乎很好,为避免嵌套,您可以返回承诺并为嵌套部分添加额外的 then 块,如下所示
initalAsyncCall()
.then((shouldContinue) => {
if (shouldContinue) {
return nextStep()
} else {
throw Error('skip next step')
}
})
.then(() => anotherStep())
.catch((error) => {
handleError(error);
})
如果您不喜欢在第三种方法中抛出不必要的错误,您可以使用 async/await 来获得更多控制并摆脱函数范围/嵌套问题,由于更好的错误堆栈,新的 nodejs 版本也建议使用此方法痕迹。
try {
const shouldContinue = await initalAsyncCall()
if (shouldContinue) {
await nextStep()
await anotherStep()
// or await Promise.all([nextStep(), anotherStep()]) if they're not dependent
}
}
catch (error) {
handleError(error);
}
推荐阅读
- html - 我如何在 explorer 11 中使用 FrameSet?
- selenium - 使用 Selenium 框架截屏时发生“TypeError: rootNode is null”
- r - 只有当它们与上面和下面的行相同时,如何删除行?
- python - 过滤日期在多个给定日期的 +/-30 天内的数据
- ios - 从 -traitCollection 返回 nil,这在 Xcode 11 Beta 中是不允许的
- amazon-web-services - 如何解决错误““消息”:“用户:匿名无权执行:iam:PassRole on resource”
- vue.js - 如何居中对齐表格 - PDFMAKE
- c# - asp:GridView -> asp:TemplateField 调用公共方法在控件内部不可用
- javascript - 使用 javascript/jQuery 从路径获取图像时发现重复的结果
- javascript - 谷歌分析页面数据和 api 响应之间是不同的