我正在尝试将一些数据库数据与本地数据同步。具体来说,我想从数据库中“加载” 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(…, …) 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仅拒绝出现不可接受的错误,否则以合理的结果实现。

09-25 17:55