简体   繁体   中英

Calling async function returning promise object using typescript on expo

Trying to return different functions (with views) on typescript expo, based on a condition set on activeStorage.

If you look in the code, when showIntro is called, I want to to show the value that's returned from getScreen but instead, when I console log, it's returning a promise object

When I console log await AsyncStorage.getItem('showIntro'); inside getScreen it's giving me the value. Not sure if it's a bug or if there's something wrong with the code?

import AsyncStorage from '@react-native-community/async-storage'

const data = [{...}, {...}, {...}]

const getScreen = async () => {
  return await AsyncStorage.getItem('showIntro'); 
}

function App() {
  const [showIntro, updateShowIntro] = React.useState(getScreen());

  const onDone = () => {
     AsyncStorage.setItem('showIntro', false).then(()=>{});
     updateShowIntro(false);
  }

  return (
  { (showIntro) ? (
      <AppIntroSlider
        renderItem={renderItem}
        data={data}
        onDone={onDone}/>
      ) : (
        <ShowApp />
      )
    }
  );
 }

Your getScreen returns a Promise since you're using async/await . What you need to do is to call getScreen when your component loads for the first time inside of a React.useEffect hook, then update your showIntro state after it resolves with whatever value you're expecting.

Using an async/await function to "wait" for AsyncStorage.getItem("showIntro") to resolve with some value before returning has really no effect - you are still dealing with a Promise that resolves once the "inner" Promise completes.

From MDN:

The return value is a Promise which will be resolved with the value returned by the async function, or rejected with an exception thrown from, or uncaught within, the async function.

import AsyncStorage from '@react-native-community/async-storage'

const data = [{...}, {...}, {...}]

// no need for `async/await` here, using `async/await`
// turns your `getScreen` function into a `Promise`, 
// you get the same exact result, so you might as well 
// call your `AsyncStorage.getItem("showIntro")` function
// directly in the `React.useEffect` hook rather than
// through this `getScreen` function
const getScreen = () => {
  return AsyncStorage.getItem("showIntro");
}

function App() {
  const [showIntro, updateShowIntro] = React.useState(null);

  React.useEffect(() => {
    getScreen()
      .then(result => {
        updateShowIntro(result);
      });
      .catch(/* handle errors appropriately */);

    // alternatively, just call `AsyncStorage.getItem("showIntro")` here
    // AsyncStorage.getItem("showIntro")
    //   .then(result => { updateShowIntro(result); })
    //   .catch(/* handle errors appropriately */);
  }, []);

  const onDone = () => {
     // should `updateShowIntro` be inside `then`?
     AsyncStorage.setItem('showIntro', false)
       .then(() => {
         updateShowIntro(false);
       })
       .catch(/* handle errors appropriately */);
  }

  return showIntro ? (
    <AppIntroSlider
      renderItem={renderItem}
      data={data}
      onDone={onDone}
    />
  ) : (
    <ShowApp />
  );
 }

References:

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