Search code examples
javascriptasync-awaites6-promise

Javascript async function return then-catch promise?


Introduction

I am new in the world of javascript promises and I need to understand how they work correctly...

Until know I have been doing this in my code:

  const handleRefresh = () => {
    setIsRefreshing(true);

    fetchUserData()
      .then(async () => { <--------- Using then because I return a promise in fetchUserData
         await fetchUserPosts(); <------- Using await here
         setIsRefreshing(false);
      }).catch(err => { <--------- This will catch the error I have thrown in the function fetchUserPosts or inside the then body
       // TODO - Show error
       setIsRefreshing(false);
       console.log(err)
    );
  };

  const fetchUserData = async () => { <------ async function
    const { firebase } = props;

    const userId = firebase.getCurrentUser().uid;

    const documentRef = firebase.getDatabase().collection("users").doc(userId);

    // Fetch all the user information
    return documentRef <--------- Returning the promise here
      .get()
      .then((doc) => {
        if (doc.exists) {
          // Get all user data
          const data = doc.data();
          console.log(data);
          setUserData(data);
        }
      })
      .catch((err) => {
        throw err; <----------- Throwing error
      });
  };

I don't know if I am doing anti patterns... But basically I need to know if this is a good way and if I am doing this correctly.

Questions

  1. Do I have to declare the fetchUserData function as async to return a promise?

  2. Can I use the async await in the then/catch body?

  3. Can I do this?

    const handleRefresh = async () => {
     setIsRefreshing(true);
    
     await fetchUserData()
       .then(async () => { <--------- Using then because I return a promise in fetchUserData
          await fetchUserPosts(); <------- Using await here
       }).catch(err => { <--------- This will catch the error I have thrown in the function fetchUserPosts or inside the then body
         // TODO - Show error
         console.log(err)
       );
       setIsRefreshing(false);
    };
    

I would really appreciate if someone guides me. Thanks.


Solution

  • the words async and await are only syntactic sugar for then and catch.

    This:

      fetchUserData()
        .then(data => return data )
        .catch(error => return error)
    

    is equivalent to:

     async function getUserData() {
       const userData = await fetchUserData()
    
       return userData
     }
    

    Here you are returning anything (success or error). If you want to treat the error here, just put a try/catch clause.

      async function getUserData() {
       try {
         return await fetchUserData()
       } catch (e) {
         return e.message
       }
     }
    

    Note that you can only use the await clause within an async function.