简体   繁体   中英

AsyncStorage in a non async function

The following code:

 _loginAsync = async () => {
    fetch('localhost:3000/login')
      .then((response) => response.json())
      .then((responseJson) => {
        await AsyncStorage.setItem('my-item', responseJson.item);
        this.props.navigation.navigate('Home');
      })
      .catch((error) => {
        console.error(error);
      });
  }

throws the error: Can not use keyword 'await' outside an async function .

Which is the proper way to valorize the my-item ?

Your .then callback isn't marked as async , only the outer _loginAsync function is.

 _loginAsync = async () => {
    fetch('localhost:3000/login')
      .then((response) => response.json())
      .then(async (responseJson) => {
        await AsyncStorage.setItem('my-item', responseJson.item);
        this.props.navigation.navigate('Home');
      })
      .catch((error) => {
        console.error(error);
      });
  }

That said, it seems weird to mix all of the .then and await forms here.

Using Async/Await Only

I think this is the most readable version. We just use async/await to await the fetch directly instead of working with its promise.

 _loginAsync = async () => {
    try {
        const response = await fetch('localhost:3000/login');
        await AsyncStorage.setItem('my-item', response.json().item);
        this.props.navigation.navigate("Home")
    } catch(error) {
        console.error(error);
    }
  }

Using Promises Directly

You can (pretty much) always use an async function as a normal function that returns a promise as well. So instead of await ing AsyncStorage.setItem we can just use its promise as part of our chain by returning it from then .

 _loginAsync = () => {
    fetch('localhost:3000/login')
      .then((response) => response.json())
      .then((responseJson) => AsyncStorage.setItem('my-item', responseJson.item))
      .then(() => this.props.navigation.navigate('Home'))
      .catch((error) => {
        console.error(error);
      });
  }

If you have to make it work for your code, make the anonymous function for the block where await occurs to async .

_loginAsync = async () => {
    fetch('localhost:3000/login')
      .then((response) => response.json())
      .then(async (responseJson) => {
        await AsyncStorage.setItem('my-item', responseJson.item);
        this.props.navigation.navigate('Home');
      })
      .catch((error) => {
        console.error(error);
      });
  }

But I prefer this is a much better approach and looks more readable. Try this code instead.

_loginAsync = async () => {
    try {
        const response = await fetch('localhost:3000/login');
        const responseJson = response.json()
        await AsyncStorage.setItem('my-item', responseJson.item);
        this.props.navigation.navigate('Home');
    } catch (error) {
        console.error(error);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM