【问题标题】:React Native - async/await does not workReact Native - 异步/等待不起作用
【发布时间】:2017-10-19 12:37:54
【问题描述】:

是否可以在类之外使用 async/await? 例如,我使用 AsyncStorage 存储访问令牌,并希望在 StackNavigator 初始化之前获取此令牌。

container.js

import React from 'react';
import { StackNavigator } from 'react-navigation';
import PairingView from '../components/PairingView';
import MainView from '../components/MainView';
import { getTokenFromStorageAsync } from '../helpers/asyncStorageHelper';

const accessToken = getTokenFromStorageAsync().done();
console.log(accessToken);   <---------- undefined

const AppNavigator = StackNavigator({
  PairingRoute: {
    screen: PairingView
  },
  MainRoute: {
    screen: MainView
  }
}, {
  initialRouteName: (accessToken == null) ? 'PairingRoute' : 'MainRoute',
  initialRouteParams: {
    token: accessToken
  }
});

const App = () => (
  <AppNavigator />
);

export default App;

asyncStorageHelper.js

import { AsyncStorage } from 'react-native';

export const getTokenFromStorageAsync = async () => {
  try {
    const value = await AsyncStorage.getItem('@nfs:token');
    console.log(value);   <---------- access token
    if (value != null)
      return value;
  } catch (err) {
    console.error(err);
  }
  return undefined;
};

【问题讨论】:

  • const accessToken = await getTokenFromStorageAsync();
  • @ponury-kostek await 只能用于异步函数
  • 对不起我的错误。所以改成getTokenFromStorageAsync().then(token => console.log(token));
  • async/await 是今年发布 (ES2017) 的一部分,而不是去年发布 (ES7/ES2016) 的一部分。请阅读标签说明。

标签: javascript react-native


【解决方案1】:

解决了这个问题。

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      accessToken: 'fetching'
    };

    this._loadAccessToken();
  }

  _loadAccessToken = async () => {
    const token = await getTokenFromStorageAsync();
    this.setState({ accessToken: token });
  }

  render() {
    if (this.state.accessToken === 'fetching')
      return null;

    const AppNavigator = StackNavigator({
      PairingRoute: {
        screen: PairingView
      },
      MainRoute: {
        screen: MainView
      }
    }, {
      initialRouteName: (this.state.accessToken == null) ? 'PairingRoute' : 'MainRoute',
      initialRouteParams: {
        token: this.state.accessToken
      }
    });

    return <AppNavigator />;
  }
}

export default App;

【讨论】:

  • 你能解释一下你做了什么来修复它吗?
  • @Noitidart 所以,有问题我试图从组件之外的 AsyncStorage 中获取价值。它不会起作用,因为await 不能在没有异步功能的情况下使用。我只是将它移动到组件内并做任何我想做的事情。
【解决方案2】:
getTokenFromStorageAsync().then(accessToken => {
    console.log(accessToken);
    // ...
});

或

// ...
export default (async () => {

    const accessToken = await getTokenFromStorageAsync();
    console.log(accessToken);

    const AppNavigator = StackNavigator({
      PairingRoute: {
        screen: PairingView
      },
      MainRoute: {
        screen: MainView
      }
    }, {
      initialRouteName: (accessToken == null) ? 'PairingRoute' : 'MainRoute',
      initialRouteParams: {
        token: accessToken
      }
    });

    const App = () => (
      <AppNavigator />
    );

    return App;

})()

如您所见,您必须导出与您的应用程序一起解析的承诺,而不是直接导出您的应用程序。

编辑:

import { AppRegistry } from 'react-native';
import App from './app/container';
(async () => {
    let ResolvedApp = await App()
    AppRegistry.registerComponent('someappname', () => ResolvedApp);
    // ...
})()

【讨论】:

  • 以及如何与 AppNavigator 一起使用?
  • 我不明白你的问题。
  • 'import' 和 'export' 只能出现在顶层
  • 哦,我明白你的意思了。你必须导出一个承诺,然后你的App 解决。
  • 以及如果我将getTokenFromStorageAsync 作为 Promise 导入。我想在没有.then 或.done 的情况下执行此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-02
  • 2019-03-17
  • 1970-01-01
  • 2023-04-07
  • 2021-06-16
相关资源
最近更新 更多