2017-10-06 81 views
-1

我正在使用Node/Express編寫註冊系統,我正在嘗試使用Promise。中斷承諾鏈 - 停止執行下一個'然後'

的問題是,我得到使用它們時的錯誤消息:

錯誤:

(node:64725) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2):

有沒有辦法停在then

auth.isRegistered(email) 
.then((registered) => { 
    if (!registered) { 
     req.flash('pleaseRegister', 'Looks like you haven\'t registered. Please register first.'); 
     req.session.user = user; 
     res.redirect('/register') 
    } 
}) 
.then(() => { 
    return auth.isVerified(email); 
}) 
.then((verified) => { 
    if (!verified) { 
     console.log('please verify'); 
     res.redirect('/register/verify'); 
    } else { 
     req.login(user, err => { 
      if (err) return next(err); 
      req.session.timestamp = Date.now(); 
      auth.updateLastLogin(email) 
      .then(() => { 
       res.redirect(req.session.returnTo || '/account'); 
      }); 
     }); 
    } 
}); 
+1

首先,你的錯誤看起來像是一個警告。其次,你有沒有嘗試在你的承諾中增加一個「catch」電話? –

+0

'if' /'else'就像你在最後一次'then'回調中應該沒問題,對'if(!registered)'做同樣的處理。 – Bergi

+0

哪個承諾被拒絕,有什麼錯誤?你從來沒有看到任何你創造的承諾的錯誤,所以這似乎是預料之中的。 – Bergi

回答

-2

你必須return當你想「停止」一個承諾時。或者Promise.resolvePromise.reject()

在這種情況下,例如:

if (!registered) { 
 
    req.flash('pleaseRegister', 'Looks like you haven\'t registered. Please register first.'); 
 
    req.session.user = user; 
 
    return res.redirect('/register') 
 
}

+3

從'then()'回調返回不會停止下一個'then()'。 –

-1

UnhandledPromiseRejectionWarning:未處理的承諾拒絕(拒絕ID:2): 我相信這是因爲你沒有一個方式來處理您的最初.thens錯誤,因此你會得到上述錯誤。它不是「停止」。然後,但正確處理錯誤。你可以做(​​err)=> {return},它基本上「停止」它,但它的流程控制在你的應用程序中。

-1

還不清楚其中then()您正在嘗試停止。但是,如果你想要邏輯和分支,你最好不要鏈接在哪裏。所以把事情放在if/else中,因此每個分支的結尾都是某種單一的響應。就我個人而言,如果可能的話,我認爲最好將自己的中間件註冊和驗證測試。我沒有在示例中包含它,但是您可以考慮添加catch()來處理錯誤。

auth.isRegistered(email) 
.then((registered) => { 
    if (!registered) { 
     req.flash('pleaseRegister', 'Looks like you haven\'t registered. Please register first.'); 
     req.session.user = user; 
     return res.redirect('/register') 
    } 
    return auth.isVerified(email) 
    .then((verified) => { 
     if (!verified) { 
      console.log('please verify'); 
      return res.redirect('/register/verify'); 
     } 
     req.login(user, err => { 
      if (err) return next(err); 
      req.session.timestamp = Date.now(); 
      auth.updateLastLogin(email) 
      .then(() => res.redirect(req.session.returnTo || '/account')); 

     }) 
    })  
}) 
+1

不要使用'else'語句,而應該使用_return early_。避免使用太多的嵌套承諾鏈。而且您不會返回由'auth.isVerified'創建的承諾,所以您仍然可以獲得'UnhandledPromiseRejectionWarning'。 – alexmac

+0

@alexmac是的,當然,謝謝。 –

0

你可以做到以下幾點:

  1. 引發自定義錯誤,當你想打破諾言鏈。
  2. 檢查catch回調拋出的錯誤是一個自定義錯誤。如果是的話,就繼續下去,否則調用nexterror對象:

例子:

let getBreackChainError =() => { 
    let err = new Error(); 
    err.name = 'BreackChainError'; 
    return err; 
}; 

auth 
    .isRegistered(email) 
    .then(registered => { 
     if (!registered) { 
     req.flash('pleaseRegister', 'Looks like you haven\'t registered. Please register first.'); 
     req.session.user = user; 
     res.redirect('/register'); 
     throw getBreackChainError(); 
     } 
     return auth.isVerified(email); 
    }) 
    .then(verified => { 
     if (!verified) { 
     console.log('please verify'); 
     res.redirect('/register/verify'); 
     throw getBreackChainError(); 
     } 
     return new Promise((resolve, reject) => { 
     req.login(user, err => { 
      if (err) { 
      return reject(err); 
      } 
      req.session.timestamp = Date.now(); 
      resolve(); 
     }); 
     }); 
    }) 
    .then(() => auth.updateLastLogin(email)) 
    .then(() => res.redirect(req.session.returnTo || '/account'); 
    .catch(err => { 
    if (err.name !== 'BreackChainError') { 
     next(err); 
    } 
    }); 

注意。你不應該將回調與承諾混合使用,使用一個。在上面的例子中,I promisifiedreq.login,所以現在它返回一個承諾。

+0

Downvoter,請解釋我的回答有什麼問題? – alexmac

+0

我拋出「getBreackChainError」,然後node.js退出腳本......我希望它停止承諾鏈不會退出整個事情! – AKMorris

+0

發現問題 - 我使用的是Promise.reject,而不是通過函數參數傳遞拒絕,如果任何人都可以快速解釋爲什麼id讚賞它,如果沒有生病創建我自己的線程。 – AKMorris