javascript - 确保在承诺链中发生某些步骤或提前停止链
问题描述
我正在尝试将一些数据库数据与本地数据同步。具体来说,我想从数据库中“加载”一个 LinkTable(加载函数本身处理数据的合并),然后,在加载函数之后,我想将 LinkTable 推送到数据库。完成后,期望的结果将是 LinkTable 的数据库和本地版本相同。更复杂的是,加载函数可以以可接受的方式拒绝......如果是这种情况,我需要继续沿着承诺链。
最后,在LinkTable 同步之后...我需要执行依赖于所述 LinkTable 的其他任务。
我正在使用 react/redux,但问题更多的是关于承诺。
相关(失败)代码如下所示:
dispatch(loadLinkTableFromDB(username))
.then((successLoadLinkTableMsg) => {
console.log('Successfully loaded link table: ', successLoadLinkTableMsg)
return dispatch(pushLinkTableToDB(username))
})
.catch((rejectLoadLinkTableReason) => {
console.log("Failed to load link table from DB: " + rejectLoadLinkTableReason);
if (allReasonsAcceptableForOverwrite(rejectLoadLinkTableReason)) { // some rejection reasons are accectable... so if failed reason is okay....
return dispatch(pushLinkTableToDB(username));
} else {
// console.log("Rejecting: ", rejectLoadLinkTableReason);
return Promise.reject(rejectLoadLinkTableReason);
}
})
.catch((unacceptableRejectionReasons) => {
console.log('unacceptableRejectionReasons :', unacceptableRejectionReasons);
})
.then(( *do more stuff that relies on the LinkTable *))
我的问题是加载 LinkTable 时的不可接受的拒绝......以及从第一个捕获中推送链接表的任何形式的拒绝最终被第二个捕获捕获。当这是一个不可接受的拒绝时,我希望整个承诺链结束。当它是一个可接受的拒绝,然后是 pushLinkTableToDB 中的后续拒绝......我希望承诺链继续。
解决方案
您将希望使用.then(…, …)
而不是.then(…).catch(…)
仅处理来自loadLinkTableFromDB
但不来自的拒绝pushLinkTableToDB
:
dispatch(loadLinkTableFromDB(username))
.then(loadLinkTableResultMsg) => {
console.log('Successfully loaded link table: ', loadLinkTableResultMsg)
return dispatch(pushLinkTableToDB(username))
}, loadLinkTableErrorReason => {
console.log('Failed to load link table from DB: ', loadLinkTableErrorReason);
if (allReasonsAcceptableForOverwrite(loadLinkTableErrorReason)) {
return dispatch(pushLinkTableToDB(username));
} else {
throw loadLinkTableErrorReason;
}
})
.then( /* do more stuff that relies on the LinkTable */ )
.catch(unacceptableRejectionReasons => {
console.log('unacceptableRejectionReasons :', unacceptableRejectionReasons);
})
但是,如果您希望pushLinkTableToDB
在这两种情况下都这样做,您可能希望将其向下移动并删除重复项:
dispatch(loadLinkTableFromDB(username))
.then(loadLinkTableResultMsg) => {
console.log('Successfully loaded link table: ', loadLinkTableResultMsg)
}, loadLinkTableErrorReason => {
console.log('Failed to load link table from DB: ', loadLinkTableErrorReason);
if (!allReasonsAcceptableForOverwrite(loadLinkTableErrorReason)) {
throw loadLinkTableErrorReason;
}
})
.then(() => dispatch(pushLinkTableToDB(username)))
.then( /* do more stuff that relies on the LinkTable */ )
.catch(unacceptableRejectionReasons => {
console.log('unacceptableRejectionReasons :', unacceptableRejectionReasons);
})
如果没有日志消息,您也只能使用catch
- 您只需在pushLinkTableToDB
调用之前放置它:
dispatch(loadLinkTableFromDB(username))
.catch(loadLinkTableErrorReason => {
if (!allReasonsAcceptableForOverwrite(loadLinkTableErrorReason)) {
throw loadLinkTableErrorReason;
}
})
.then(() => dispatch(pushLinkTableToDB(username)))
.then( /* do more stuff that relies on the LinkTable */ )
.catch(unacceptableRejectionReasons => {
console.log('unacceptableRejectionReasons :', unacceptableRejectionReasons);
})
如果您控制该loadLinkTableFromDB
函数,您甚至可能需要考虑将catch
调用移到该函数内部,这样返回的 Promise只会拒绝不可接受的错误,否则会以合理的结果实现。
推荐阅读
- java - 转换字符串时的 Java 代码效率
- javascript - 最小化浏览器重绘:javascript中最简单的交集代码不起作用
- python - 循环数据帧时的效率提高
- c++ - 如何自定义可以使用时间戳的 QSlider?
- c# - 使用键盘上的标签按钮时,标签页不会获得焦点
- javascript - 不能在类组件中调用 React Hook “useState”。必须在 React 函数组件或自定义 React Hook 函数中调用 React Hooks
- android - 如何在kotlin中通过retrofit2获取json
- javascript - 反应原生 | 动态变量
- c# - C# 合并值相同的单元格
- laravel - Browsershot:每张纸显示两页