Javascript 如何在承诺范围内处理分支?

Javascript 如何在承诺范围内处理分支?,javascript,asynchronous,promise,Javascript,Asynchronous,Promise,我正在用AWS Cognito实现一个无密码的身份验证流。它支持与UI相关的逻辑,因此我倾向于选择仅使用Promise(无async&wait)不阻塞线程。做下面这样的事情仍然让我觉得,我在写另一个“承诺版”的回调地狱 const session = await getSession(); if (!session) { try { const user = await signUp(emailAddress); } catch (error) {

我正在用AWS Cognito实现一个无密码的身份验证流。它支持与UI相关的逻辑,因此我倾向于选择仅使用
Promise
(无
async
&
wait
)不阻塞线程。做下面这样的事情仍然让我觉得,我在写另一个“承诺版”的回调地狱

  const session = await getSession();

  if (!session) {
    try {
      const user = await signUp(emailAddress);
    } catch (error) {
      try {
        const state = await resendConfirmationCode();
      } catch {
        await forgotPassword();
      }
    }
  }
我知道我可以使用
then
将所有函数链接在一起,但是后续
then
中的响应实际上取决于上一次
then
中得到的结果,这就是为什么我要问如何处理承诺内部的分支(或者
then

所有方法都返回
表格
。我花了很长时间才想出一种方法来实现这一点,使用纯
Promise
then
。使用
callback
s非常简单


理想情况下,我希望在没有额外lib的情况下完成这项工作。

因为您已经在使用Promissions和modern Node,所以绝对没有理由不使用它,因为它允许您同步编写异步代码

此外,让我们编写一个小助手来检查承诺流,因为您正在对流控制使用异常,这通常是一个大禁忌:

const reflect = p => p.then(value => ({ state: 'fulfilled', value }), 
                            error => ({ state: 'rejected', error }));
现在,让我们重写它,而不使用异常进行非异常流控制:

export const doInitAuth = async emailAddress => {
  if ((await reflect(getSession()).state === 'fulfilled') return; // already has a live session
  if ((await reflect(signUp(emailAddress))).state === 'fulfilled') return; // signed up successfully
  if ((await reflect(resendConfirmationCode())).state === 'fulfilled') return; // sent confirmation email
  if ((await reflect(forgotPassword())).state === 'fulfilled') return;
  // deal with what you want to do in case forgotPassword failed here  
};

<> P>你的代码看起来“奇怪”的原因是因为你使用的是流控制的异常——没有会话,不能用已注册的电子邮件注册等等。这些都是合理的,不是例外的情况,你应该考虑不使用异常。

最简短的回答是:使用函数。你不需要把所有的东西都放在一个大的街区里。一旦你添加函数并减少缩进,答案可能会变得很明显。假设这是完全同步的-会是什么样子?@BenjaminGruenbaum给我一点时间让我编写一个同步版本。@Xiangli留下了答案,我不确定这是你的意思还是你想要的,但请告诉我它是否适合你-它也可以做得更短-但在我看来,这会损害可读性,所以我选择了相对详细。但我担心的是使用
async
wait
会阻止用户界面的更新,对吗?我正在连接一个浏览器端解决方案,而不是在NodeJS中。@xiningli异步/await的全部要点是,它与阻塞一样简单,但不阻塞。这就是它的美妙之处。作为一个编写了多个promise库并帮助维护了一些最大的promise库(bluebird,Q)的人,我为Node.js编写promises-我再也不会在没有async/await的情况下编写promises了:)这就是async/await如此出色的原因,它只是一个隐藏的承诺。它在后台保留一个状态机,该状态机使用与承诺链(和生成器)相同的机制,并在承诺解析时保留状态并重新进入函数。它仍然是基于事件和异步的。好的,谢谢@benjamin,我想我需要理解
async
更多,阅读@XinyangLi当然,这是一本非常好的书(我是一名评论员)-如果你对此有任何问题,请毫不犹豫地在这里询问,或者给我或axel发电子邮件。很高兴我能帮忙!
export const doInitAuth = async emailAddress => {
  if ((await reflect(getSession()).state === 'fulfilled') return; // already has a live session
  if ((await reflect(signUp(emailAddress))).state === 'fulfilled') return; // signed up successfully
  if ((await reflect(resendConfirmationCode())).state === 'fulfilled') return; // sent confirmation email
  if ((await reflect(forgotPassword())).state === 'fulfilled') return;
  // deal with what you want to do in case forgotPassword failed here  
};