2017-10-06 51 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