简体   繁体   中英

Why is my promise function returning before finished

In my header component:

signIn() {
  signInWithPopup(auth, provider).then((result) => {
    this.updateUser(result.user.uid);
    const userRef = doc(db, 'users', result.user.uid);
    this.firestoreUser(userRef)
    .then((userDoc) => {
      if (!userDoc.exists()) {
        this.addNewUserToFirestore(userRef, result.user);
      }
    })
    .then(() => {
      console.log('Read user from firestore');
      // FIXME: readUserFromFirestore still isn't finishing before moving on...
      this.readUserFromFirestore();
    })
    .then(() => {
       console.log('Read personal patches');
       this.readPersonalPatches();
    })
    .then(() => {
      console.log('Add watcher');
      this.geolocationId = navigator.geolocation.watchPosition(
        this.nearLandmark,
        this.errorCallback
      );
    });
  });
},

readUserFromFirestore:

async readUserFromFirestore({ commit, state }) {
    const userRef = doc(db, 'users', state.user);
    try {
      const userDoc = await getDoc(userRef);

      await (() => {
        return new Promise((resolve) => {
          for (const property in userDoc.data()) {
            const propertyValue = userDoc.data()[property];
            commit('addProfileProperty', {
              propertyName: property,
              propertyValue,
            });
          }
          console.log(
            'Just finished putting in user patches',
            state.profile.patches
          );
          resolve();
        });
      })();
    } catch (e) {
      alert('Error!');
      console.error(e);
    }
  },
};

readPersonalPatches:

async readPersonalPatches({ commit, state }) {
  try {
    if (state.user) {
      // Get a copy of all the user's patches
      state.ownedPatchesArray = [];
      state.unownedPatchesArray = [];
      await (function () {
        console.log('Made it inside the await from readpersonalpatches');
        return new Promise((resolve) => {
          console.log('raw badges', state.rawPatches);
          console.log('user badges', state.profile.patches);
          state.rawPatches.forEach((patch) => {
            if (JSON.stringify(state.profile.patches).includes(patch.slug)) {
              commit('addToArray', {
                arr: 'ownedPatchesArray',
                value: patch,
              });
            } else {
              commit('addToArray', {
                arr: 'unownedPatchesArray',
                value: patch,
              });
            }
          });

          resolve();
        });
      })();
    }
  } catch (error) {
    alert('Error reading personal patches');
    console.log(error);
  }
},

Console Output:

Read user from firestore
Read personal patches
Made it inside the await from readpersonalpatches
raw badges **accurate badge list**
user badges undefined
TypeError: Cannot read properties of undefined (reading 'includes')
Add watcher
Just finished putting in user patches **accurate user patch list**

In readUserFromFirestore I wasn't sure exactly how to approach waiting on the user's patches to be added to the array before moving on in the sign-in process. One of the properties that is being looped over is profile.patches . readPersonalPatches() uses that property. But on fresh logins I get an error in readPersonalPatches() because profile.patches is undefined at that point. (On logins after cacheing I do not have an issue reading profile.patches apart from the data potentially being outdated.)

I am using Vue, Vuex, and Firebase for Authentication and Firestore. For my purposes patch and badge are interchangeable terms.

Thanks to Luaan for educating me on how then blocks work I have it going now. I wasn't returning the promises, only calling the function and then not doing anything with the returned promises

Fixed lines:

    .then((userDoc) => {
      return (function () {
        if (!userDoc.exists()) {
          this.addNewUserToFirestore(userRef, result.user);
        }
      })();
    })
    .then(() => {
      console.log('Read user from firestore');      
      return this.readUserFromFirestore();
    })
    .then(() => {
       console.log('Read personal patches');
       return this.readPersonalPatches();
    })

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