如何在不声明异步的情况下等待 Promise

How to await Promise without declaring async

我正在编写一个 React Native 应用程序。有没有办法在返回值之前解决非异步函数中的 Promise?

样本:

const f = () => {
  return new Promise((resolve) => {
    resolve('baz')
  })
}

const foo = () => {
  const a = f() // a is now a Promise
  return a
};

console.log(foo) // `foo` is a Promise, I need 'baz'

我想找到一种方法从 f 中获取已解析的值,但我无法使 foo() 异步。有没有办法做到这一点? 如果没有,有什么想法可以解决这个问题吗?

这是我经过一些清理后的真实代码:

const stackNavigator = new StackNavigator(...)
const defaultGetStateForAction = stackNavigator.router.getStateForAction

stackNavigator.router.getStateForAction = (action, state) => {

  let screenToRequest = undefined
  let defaultState = undefined

  const isInitial = action.type === 'Navigation/INIT'

  if (isInitial) {
    defaultState = MainTabs.router.getStateForAction('Navigation/INIT')
    screenToRequest = defaultState.routes[defaultState.index].routeName
  } else if (action.type === 'Navigation/NAVIGATE') {
    screenToRequest = action.routeName
  }

  if (screenToRequest) {
    const screen = screens.getScreen(screenToRequest)

    /**
     * If screen requires login, check if user is logged in
     */
    if (screen.screen.loginRequired) {
      /**
       * Here I would like to read data from AsyncStorage with
       * `await` but that's not possible due to this function
       * not being `async` and it cannot be since router does not
       * seem to support it.
       *
       * getSession() reads data from AsyncStorage. If I could
       * `await getSession()`, I would not have a problem.
       */
       const session = getSession()

       // Use `session` to determine if user is logged and act accordingly
    }
  }

  return defaultGetStateForAction(action, state);
};

快速而肮脏:您可以将 foo() 变成轮询函数。

只需创建一个 setInterval 每隔一段时间轮询一次并检查 Promise 解析时由 f() 更新的值。

编辑:

对不起,我想我误读了你的问题。你做不到 async。好吧,那么你可以这样做:

const foo = async () =>{
  await const a = f() // a is now a Promise
  return a // a will not be returned until f() resolves
};

这将使函数同步(阻塞)。当你调用它时,如果你需要保持同步,你也会想要 await 它:

{
  bar: async () =>{
    await foo();
    return; // dont return until foo() resolves
  }
}

感觉您可能需要重新考虑一下您的架构。如果您正在执行一项操作(比如说网络请求),而您的应用程序的其他部分需要该数据才能运行,那么您只有两种选择。您可以暂停一切并等待 (async/await),或者您可以让您的应用在没有该数据的情况下优雅地继续运行,然后在它可用时自行更新。两种选择都很棒,它只取决于你到底想做什么。

在 React/React 本机应用程序中,当您有 UI 正在等待数据从网络请求返回时,第二个选项使用得非常频繁。不是在发出请求时冻结 UI,而是在 UI 中呈现一些消息,表明数据即将到来。在您的异步函数中,当承诺得到解决时,您必须将该数据放在您的患者 UI 可以读取的地方。这就是像 Redux 或 Mobx 这样的状态管理系统的用武之地。它们给你一个存储数据的地方,然后它们发送事件来提醒你的 UI 你已经准备好了,你现在可以重新渲染所有这些漂亮的数据。

希望对您有所帮助。