首页 > 解决方案 > 试图将一个承诺函数重构为 try-catch 块

问题描述

我正在尝试使用 try-catch 块重构此代码:

export const authorizeConnectyCube = async (accessToken) => {
  const userCredentials = {
    provider: 'firebase_phone',
    'firebase_phone[project_id]': "xxxxxxxx",
    'firebase_phone[access_token]': accessToken,
  };
  await createSession();
  return new Promise((resolve, reject) => {
    ConnectyCube.login(userCredentials, (error, user) => {
      user ? resolve(user) : reject(error);
    })
  }).catch(error => console.log(error));
}

const createSession = () => {
  return new Promise((resolve, reject) => {
    ConnectyCube.createSession((error, session) => {
      session ? resolve(session.user) : reject(error)
    })
  }).catch(error => console.log(error));
}

但是我没有得到相同的结果 - 异步的处理方式似乎有所不同。这是我重构的尝试:

export const authorizeConnectyCube = async (accessToken) => {

  const userCredentials = {
    provider: 'firebase_phone',
    'firebase_phone[project_id]': "xxxxxxxxxx",
    'firebase_phone[access_token]': accessToken,
  };

  await createSession();
  try {
    ConnectyCube.login(userCredentials, (error, user) => {
      return user;
    })
  }
  catch (error) {
    console.log(error)
  }
}

const createSession = () => {
  try {
    ConnectyCube.createSession((error, session) => {
      return session.user
    })
  } catch (error) {
    console.log(error);
  }
}

我错了有什么特别的部分吗?谢谢。

标签: javascriptpromiseasync-awaittry-catch

解决方案


基于回调的 API 不容易变成可以用于async/的东西await(在底层使用 Promise)。您必须首先“承诺”它们(即将它们包装在承诺中)。

这是我想说的一个例子:

// Promisify these callback-based APIs.
const login = userCredentials => {
  return new Promise((resolve, reject) => {
    ConnectyCube.login(userCredentials, (error, user) => {
      user ? resolve(user) : reject(error);
    })
  })
})

const createSession = () => {
  return new Promise((resolve, reject) => {
    ConnectyCube.createSession((error, session) => {
      session ? resolve(session.user) : reject(error)
    })
  })
})

// Then use them in an async function
export const authorizeConnectyCube = async (accessToken) => {
  const userCredentials = {
    provider: 'firebase_phone',
    'firebase_phone[project_id]': "xxxxxxxx",
    'firebase_phone[access_token]': accessToken,
  }

  try {
    await createSession()
    return login(userCredentials)
  } catch (e) {
    console.warn(e)
  } 
}

此外,async函数返回承诺,解决的值是返回值,而拒绝的值是内部抛出的任何未捕获的错误。包装在 promise 中作为异步函数的返回值的值是多余的。

如果您使用的是 Node 8+,它有一个称为实用程序的实用程序,该实用程序promisify接受基于回调的 API 并返回它的 promise-returning 版本。


推荐阅读