javascript - 如何处理 Promise 中的分支?

标签 javascript asynchronous promise

我正在使用 AWS Cognito 实现无密码身份验证流程。它与 UI 相关的逻辑,所以我倾向于选择不阻塞线程,只使用 Promise(没有 asyncawait)。做类似下面的事情仍然让我觉得,我正在写另一个回调 hell 的“Promise 版本”。

  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 这就是为什么我要问如何处理 Promise 内的分支(或 then)的原因。

所有方法都返回thenable。我很难找到一种方法来使用纯 Promisethen 来实现它。使用 callback 非常简单。

enter image description here

export const doInitAuth = emailAddress => {
  getSession()
    .then(
      // Step 01 Check there is a current live session (Optional)
      session => {
        return null; // stopped the auth flow and dropped `session`
      },
      error => {
        // Step 02 Signup a new account
        return signUp(emailAddress).then(
          userData => {
            return null; // stopped the auth flow and dropped `userData`
          },
          error => {
            // Resend account verification code if user already signed up
            return resendConfirmationCode().then(
              result => {
                return null; // stopeed the auth flow and dropped `result`
              },
              error => {
                return forgotPassword(); // HACK: (Xinyang) There is a limit for number of time a user can "forgot" the password in a given time
              }
            );
          }
        );
      }
    )
    .catch(error => {
      throw Error("Unhandled error in the auth flow", error);
    });
};

理想情况下,我希望在没有额外库的情况下完成此操作。

最佳答案

既然您已经在使用 promises 和现代 Node - 绝对没有理由不使用 async/await它可以让你同步编写异步代码。

此外,让我们编写一个小助手来检查 promise 流程,因为您正在使用异常进行流程控制,这通常是一个很大的禁忌:

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  
};

您的代码看起来“怪异”的原因是因为您正在使用流量控制异常 - 没有 session 、无法使用已接收的电子邮件进行注册等都是合理的而不是异常情况,您应该考虑不使用他们的异常(exception)情况。

关于javascript - 如何处理 Promise 中的分支?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51540650/

相关文章:

javascript - 如何在不迭代的情况下更改所有元素的类名?

javascript - 仅在移动设备上打开 Google map 应用

javascript - 在 IIFE block 中定义一个变量

javascript - 将 jQuery 插件函数绑定(bind)到循环中的多个元素

c++ - Linux 上的异​​步套接字发送

javascript - RequireJS 在 IE9 中不工作

python - 如何在 Python 中发出异步 HTTP GET 请求并将响应对象传递给函数

javascript - 来自 2 个独立函数的顺序链接 Promise

node.js - 如何在 NodeJS 的 'finally' 子句中使用 'Promise' ?

Javascript promise : Iterate over all object keys arrays and then resolve