如何在不声明异步的情况下等待 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 你已经准备好了,你现在可以重新渲染所有这些漂亮的数据。
希望对您有所帮助。
我正在编写一个 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 你已经准备好了,你现在可以重新渲染所有这些漂亮的数据。
希望对您有所帮助。