Javascript 确保承诺链中出现某些步骤或提前停止链

Javascript 确保承诺链中出现某些步骤或提前停止链,javascript,promise,Javascript,Promise,我正在尝试将一些数据库数据与本地数据同步。具体来说,我想从数据库“加载”一个链接表(加载函数本身处理数据的合并),然后在加载函数之后,我想将链接表推送到数据库。完成后,期望的结果是数据库和本地版本的LinkTable是相同的。更复杂的是,加载函数可以以可接受的方式拒绝。。。如果是这样的话,我需要继续履行承诺 最后,在链接表同步之后。。。我需要做额外的任务,依赖于所说的链接表 我正在使用react/redux,但问题更多的是关于承诺 相关(失败)代码如下所示: dispatch(load

我正在尝试将一些数据库数据与本地数据同步。具体来说,我想从数据库“加载”一个链接表(加载函数本身处理数据的合并),然后在加载函数之后,我想将链接表推送到数据库。完成后,期望的结果是数据库和本地版本的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 *))
我的问题是加载链接表时出现不可接受的拒绝。。。任何形式的拒绝从第一个捕获推送链接表最终都会被第二个捕获捕获。当这是一个不可接受的拒绝,我希望整个承诺链结束。当它是可接受的拒绝,然后是pushLinkTableToDB中的后续拒绝时。。。我希望承诺链继续。

您只希望使用来处理来自
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);
})

如果您控制<代码> LooLink表数据DB < /Cult>函数,您甚至可能需要考虑在该函数内移动<代码> 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);
})

如果您控制<代码> LooLink表数据DB < /代码>函数,您甚至可能需要考虑在该函数内移动<代码> catch >代码>调用,以便返回的承诺仅拒绝具有不可接受的错误,否则以合理的结果满足。

提前停止链,'throw`一个错误或返回一个被拒绝的承诺不会在下一个“throw”错误中被捕获。catch()“?要尽早停止链,'throw`一个错误或返回一个被拒绝的承诺不会在下一个“throw”错误中被捕获。catch()”?是的!我已经记不清有多少次人们把
.then(successHandler,errorHandler)
描述为反模式。好吧,这并不总是合适的,但这是一个完全不同的命题。是的!我已经记不清有多少次人们把
.then(successHandler,errorHandler)
描述为反模式。好吧,这并不总是合适的,但这是一个完全不同的命题。