javascript - 确保 promise 链中发生某些步骤或提前停止链

标签 javascript promise

我正在尝试将一些数据库数据与本地数据同步。具体来说,我想从数据库“加载”LinkTable(加载函数本身处理数据的合并),然后在加载函数之后我想将 LinkTable 推送到数据库。完成后,期望的结果是数据库和 LinkTable 的本地版本将是相同的。让事情变得复杂的是,加载函数可以以可接受的方式拒绝......如果是这种情况,我需要继续沿着 promise 链前进。

最后,同步 LinkTable 后...我需要执行依赖于所述 LinkTable 的其他任务。

我正在使用react/redux,但问题更多是关于 promise 。

相关(失败)代码如下所示:

     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 时出现 Not Acceptable 拒绝...以及从第一个 catch 推送链接表时的任何类型的拒绝最终都会被第二个 catch 捕获。当这是一个 Not Acceptable 拒绝时,我希望整个 promise 链结束。当这是一个可接受的拒绝,然后是 PushLinkTableToDB 中的后续拒绝时......我希望 promise 链继续。

最佳答案

您需要使用.then(…, …) instead of .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 因 Not Acceptable 错误而拒绝,否则以合理的结果完成。

关于javascript - 确保 promise 链中发生某些步骤或提前停止链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59743498/

相关文章:

node.js - 为什么这个 Node 片段没有捕捉到被拒绝的 Promise?

javascript - 如何将返回的对象转换为对象的 promise ?

javascript - 如何在ng-repeat中水平添加数据

javascript - 如何捕获 fetch 的 then() 中的 json 文本

javascript - 在 Javascript 中对表进行排序

javascript - 从命令行控制浏览器 javascript 执行

node.js - 如何从 saveAsync 返回 Mongoose 对象?

javascript - 浏览器是否仍然默默地吞下未处理的拒绝 promise ? Node 呢?

javascript - VS Code 智能感知和 TypeScript 编译不匹配

javascript - Jquery退出弹出窗口困惑