Как я могу получить эти обещания, чтобы решить в порядке - PullRequest
0 голосов
/ 07 июня 2019

У меня проблемы с цепочками обещаний Firebase, решаемыми до завершения всей цепочки. У меня есть модал входа в систему и регистрации, который отображает ошибки пользователю при необходимости. Я строю это с VUEJs

Если ошибка связана с неправильным форматированием электронной почты, цепочка обещаний работает отлично и отображает правильное сообщение об ошибке для пользователя. Если форматирование правильное и запрос фактически отправляется в базу данных fire, то .then будет срабатывать до полного разрешения исходного обещания firebase, в результате чего в операторе метода регистрации my if всегда разрешается значение false, и происходит перенаправление на / dashboard перед ошибкой. возвращается в приложение из firebase.

Я воткнул эту штуку уже несколько часов. Я попытался реорганизовать цепочку обещаний. У меня есть вход в компонент, который ведет себя точно так же.

Вот мой метод, который срабатывает при нажатии кнопки регистрации.

computed:{
    error () {
      return this.$store.getters.error
    }
},
methods: {
  signup () {
      const userProfile = {
        userName: this.userName,
        firstName: this.firstName,
        lastName: this.lastName,
        password: this.password,
        birthDate: this.birthDate,
        address: this.address,
        city: this.city,
        state: this.state,
        zip: this.zip,
        email: this.email
      }
      if (this.email && this.password && this.userName) {
        this.$store.dispatch('signUserUp', userProfile)
          .then( () => {
            if (this.error) {
              console.log(this.error)
              return this.feedback = this.error.message
            } else {
                return this.$router.replace('/dashboard')
            }
        })
      } else {
        return this.feedback = 'Please enter all required fields'
      }
    }
}

Это действие в моем магазине Vuex, которое метод отправляет на

signUserUp({commit}, payload) {
      commit('setLoading', true)
      commit('clearError')
      let slug = null
      let newUser = {}
      let newError = {
        test: 'test',
        message: 'User Name is already taken, please chose another.'
      }
      slug = slugify(payload.userName, {
      replacement: '-',
      remove: /[$*_=~.()''!\-:@]/g,
      lower: true
      })
      firebase.database().ref('users/' + slug).once('value', snapshot => {
        if (snapshot.exists()){
          console.log('name exists')
          commit('setError', newError)
        } else {
          console.log('user does not exist')
          firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password)
          .then(
            cred => {
                newUser = {
                userId: cred.user.uid,
                userName: slug,
                firstName: payload.firstName,
                lastName: payload.firstName,
                birthDate: payload.birthDate,
                adress: payload.adress,
                city: payload.city,
                state: payload.state,
                zip: payload.zip,
                email: payload.email
              }
              console.log(newUser)
              commit('setUser', newUser)
              console.log('sign up complete')
              firebase.database().ref('/users/' + slug).set(newUser)
                .then( () => {
                commit('setLoading', false)
                console.log('user profile uploaded')
              })
              .catch( error => {
                console.log(error)
              })
            }
          )
          .catch(
            error => {
              commit('setLoading', false)
              commit('setError', error)
              console.log(error)
            }
          )
        }
      })
    }

Я пытаюсь проверить базу данных, чтобы убедиться, что имя пользователя еще не занято. Если это было сделано, я хочу показать пользователю ошибку и остаться в форме регистрации. Если нет, я хочу, чтобы он создал новую учетную запись, загрузил профиль в мою базу данных в реальном времени, а затем перенаправил на / dashboard, если все прошло успешно.

Это мое первое приложение "Сделай это на 100%", так что, пожалуйста, будьте осторожны, смеется.

Спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 07 июня 2019

Как объяснено в документации , signUserUp должно возвращать обещание, чтобы связать его с this.$store.dispatch('signUserUp', userProfile).then(...).Firebase поддерживает обещания, где это возможно.Можно связать once() и сгладить цепочку обещаний с помощью async..await:

async function signUserUp({commit}, payload) {
  try {
    ...  
    const snapshot = await firebase.database().ref('users/' + slug).once('value');
    ...
    const cred = await firebase.auth().createUserWithEmailAndPassword(payload.email, payload.password);
    ...
  } catch (error) {
    commit('setLoading', false)
    commit('setError', error)
  }
}
0 голосов
/ 07 июня 2019

Если вам нужно дождаться завершения асинхронного кода в вашем действии , тогда ваше действие должно вернуть Promise.

Вероятно, самый простой способ * заставить эту работу работать с вашим текущим кодом - это обернуть его в новый Promise.

signUserUp({commit}, payload) {
    return new Promise(function(resolve, reject) {
        /* existing function body */
    });
}

Затем добавьте вызовы к resolve() после завершения асинхронного кода. (Например, в этот момент: console.log('user profile uploaded') или после одной из ошибок.) Как только вы вызовете обратный вызов разрешения, он вызовет обработчик then в вашем методе регистрации. Вы также можете отклонить Promise, используя функцию обратного вызова. В вашем случае, однако, похоже, что вы хотите, чтобы действие обрабатывало саму ошибку, а не распространяло ее.

* Так как API Firebase использует обещания, вы также можете попытаться вернуть результат функций Firebase.

...