CleanCodeOnline
CleanCodeOnline

Reputation: 207

Why async/await and then produce different results

I'm just asking this question to clarify and get a better understanding at javascript promises. The following two codes look very similar to me, but why both gives different results. Also how to get the result of async/await function in .then way. Thanks.

async/await

const getFieldValue = async (collection, userid) => {
  let response;

  const querySnapshot = await firestore()
    .collection(collection)
    .where("userid", "==", userid)
    .get();
  querySnapshot.forEach((doc) => {
    const { name } = doc.data();
    response = name;
  });

  return response;
};
async function fetchData() {
  const name = await getFieldValue("Users", userid);
  console.log("name", name);
}
fetchData();

.then

const getFieldValue = (collection, userid) => {
  let response;

  firestore()
    .collection(collection)
    .where("userid", "==", userid)
    .get()
    .then((querySnapshot) => {
      querySnapshot.docs.find((doc) => {
        const { name } = doc.data();
        response = name;
      });
    })
    .catch((e) => console.log(e));

  return response;
};
const name = getFieldValue("Users", userid);
console.log("name", name);

async/await returns correct name and .then returns undefined

Upvotes: 2

Views: 927

Answers (2)

Aluan Haddad
Aluan Haddad

Reputation: 31823

Yep that's just what one would expect.

Remember, await effectively suspends execution until the awaited operation is complete.

In your example using .then you return immediately because you did not compose your promise chain such that response is returned only when the sequence of awaited operations completes. Rather, you return immediately with the undefined value with which response was initialized

Thus, the proper way to express your logic, otherwise unaltered, via .then would be

 const getFieldValue = (collection, userid) => {
    let response;

    return firestore() // notice the return here! This is vital
      .collection(collection)
      .where("userid", "==", userid)
      .get()
      .then((querySnapshot) => {           
        querySnapshot.docs.find((doc) => {
          const { name } = doc.data();
          response = name;
        });
      })
      .then(() => response) // notice how we resolve our promise chain with the value ultimately assigned
      .catch((e) => console.log(e));
};

Upvotes: 3

Georg Edlbauer
Georg Edlbauer

Reputation: 249

Because with async/await the execution of the function is suspended ("paused"), until the promise is resolved. Therefore your funcion waits for the result.

With .then however, your function will continue immediately with the code below the .then "block", not waiting for the promise to resolve. Because of that response is returned before it is set in the .then section and therefore still undefined.

With async/await you have to imagine that the return statement is also in the .then block.

Upvotes: 1

Related Questions