亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

處理承諾鏈中的多個漁獲

處理承諾鏈中的多個漁獲

慕后森 2019-10-15 14:24:22
我對諾言仍然還很陌生,目前正在使用藍鳥,但是在我不確定如何最好地處理它的情況下。因此,舉例來說,我在Express應用程序中有一個Promise鏈,如下所示:repository.Query(getAccountByIdQuery)        .catch(function(error){            res.status(404).send({ error: "No account found with this Id" });        })        .then(convertDocumentToModel)        .then(verifyOldPassword)        .catch(function(error) {            res.status(406).send({ OldPassword: error });        })        .then(changePassword)        .then(function(){            res.status(200).send();        })        .catch(function(error){            console.log(error);            res.status(500).send({ error: "Unable to change password" });        });所以我的行為是:通過ID獲取帳戶如果此時存在拒絕,請轟炸并返回錯誤如果沒有錯誤,則將文檔轉換為模型使用數據庫文檔驗證密碼如果密碼不匹配,則炸開并返回其他錯誤如果沒有錯誤,請更改密碼然后返回成功如果有其他問題,請返回500因此,當前的捕獲量似乎并沒有停止鏈接,這是有道理的,所以我想知道是否存在一種方法可以根據錯誤以某種方式強制鏈停止在某個點,或者是否有更好的方法構造這種形式以獲得某種形式的分支行為,例如if X do Y else Z。任何幫助都會很棒。
查看完整描述

3 回答

?
守候你守候我

TA貢獻1802條經驗 獲得超10個贊

此行為完全類似于同步拋出:


try{

    throw new Error();

} catch(e){

    // handle

// this code will run, since you recovered from the error!

那是.catch要從錯誤中恢復的一半??赡苄枰匦聮伋鲂盘栆灾甘緺顟B仍然是錯誤:


try{

    throw new Error();

} catch(e){

    // handle

    throw e; // or a wrapper over e so we know it wasn't handled

// this code will not run

但是,僅此一種方法對您而言不起作用,因為該錯誤將由以后的處理程序捕獲。真正的問題是,廣義的“ HANDLE ANYTHING”錯誤處理程序通常是一種不好的做法,在其他編程語言和生態系統中卻極少使用。因此,藍鳥提供了類型化和謂詞性的捕獲。


附加的優點是您的業務邏輯根本不需要(也不應該)知道請求/響應周期。決定客戶端獲取哪種HTTP狀態和錯誤不是查詢的責任,而隨著應用的增長,您可能希望將業務邏輯(如何查詢數據庫以及如何處理數據)與發送給客戶端的內容分開(什么http狀態代碼,什么文本和什么響應)。


這是我編寫您的代碼的方式。


首先,我將.Query拋出一個NoSuchAccountError,將其從Promise.OperationalErrorBluebird已經提供的子類化。如果您不確定如何將錯誤歸類,請告訴我。


我另外為其子類化AuthenticationError,然后執行類似的操作:


function changePassword(queryDataEtc){ 

    return repository.Query(getAccountByIdQuery)

                     .then(convertDocumentToModel)

                     .then(verifyOldPassword)

                     .then(changePassword);

}

如您所見-它非常干凈,您可以閱讀文本,就像使用說明書一樣,了解過程中發生的情況。它也與請求/響應分開。


現在,我將從路由處理程序中這樣調用它:


 changePassword(params)

 .catch(NoSuchAccountError, function(e){

     res.status(404).send({ error: "No account found with this Id" });

 }).catch(AuthenticationError, function(e){

     res.status(406).send({ OldPassword: error });

 }).error(function(e){ // catches any remaining operational errors

     res.status(500).send({ error: "Unable to change password" });

 }).catch(function(e){

     res.status(500).send({ error: "Unknown internal server error" });

 });

這樣,邏輯就全部集中在一個地方,而如何為客戶處理錯誤的決定就都集中在一個地方,而且它們不會相互干擾。


查看完整回答
反對 回復 2019-10-15
?
LEATH

TA貢獻1936條經驗 獲得超7個贊

.catch就像try-catch語句一樣工作,這意味著最后只需要一個捕獲即可:


repository.Query(getAccountByIdQuery)

        .then(convertDocumentToModel)

        .then(verifyOldPassword)

        .then(changePassword)

        .then(function(){

            res.status(200).send();

        })

        .catch(function(error) {

            if (/*see if error is not found error*/) {

                res.status(404).send({ error: "No account found with this Id" });

            } else if (/*see if error is verification error*/) {

                res.status(406).send({ OldPassword: error });

            } else {

                console.log(error);

                res.status(500).send({ error: "Unable to change password" });

            }

        });


查看完整回答
反對 回復 2019-10-15
?
HUWWW

TA貢獻1874條經驗 獲得超12個贊

我想知道是否存在一種方法可以根據錯誤以某種方式強制鏈條停止在某個點


不可以。除非您拋出一個冒泡直到結束的異常,否則您無法真正“終止”一條鏈。


他的模式的派生將不是區分錯誤類型,而是使用具有statusCode和body字段的錯誤,這些錯誤和字段可以從單個通用.catch處理程序發送。根據您的應用程序結構,他的解決方案可能會更干凈。


或者是否有更好的方法來構造它以獲得某種形式的分支行為


是的,您可以使用promises進行分支。但是,這意味著離開鏈并“返回”嵌套-就像您在嵌套的if-else或try-catch語句中所做的那樣:


repository.Query(getAccountByIdQuery)

.then(function(account) {

? ? return convertDocumentToModel(account)

? ? .then(verifyOldPassword)

? ? .then(function(verification) {

? ? ? ? return changePassword(verification)

? ? ? ? .then(function() {

? ? ? ? ? ? res.status(200).send();

? ? ? ? })

? ? }, function(verificationError) {

? ? ? ? res.status(406).send({ OldPassword: error });

? ? })

}, function(accountError){

? ? res.status(404).send({ error: "No account found with this Id" });

})

.catch(function(error){

? ? console.log(error);

? ? res.status(500).send({ error: "Unable to change password" });

});


查看完整回答
反對 回復 2019-10-15
  • 3 回答
  • 0 關注
  • 601 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號