繁体   English   中英

确保某些步骤发生在承诺链中或尽早停止链

[英]Ensuring certain steps occur in promise chain or stopping chain early

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

最后,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 时出现了不可接受的拒绝......以及从第一个捕获中推送链接表的任何类型的拒绝最终都会被第二个捕获所捕获。 当这是一个不可接受的拒绝时,我希望整个承诺链结束。 当它是一个可接受的拒绝,然后在 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调用移到该函数内,以便返回的承诺因不可接受的错误而拒绝,否则以合理的结果实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM