Как вызвать ошибку во внешней функции из внутренней асинхронной функции c, например, setTimeout в JavaScript? - PullRequest
1 голос
/ 17 апреля 2020

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

export const userSignin = (email, password) =>
  async dispatch => {
    try {
      dispatch({ type: 'auth_attempt_started' })
      const user = await firebase.auth().signInWithEmailAndPassword(email.trim(), password)
      saveUserDataToAsyncStorage(user)
      if (!TASKS_SORT_BY && !TASKS_SORT_ORDER)
        dispatch(getTasksSortData(user.user.uid))
      if (!EMPLOYEES_SORT_BY && !EMPLOYEES_SORT_ORDER)
        dispatch(getEmployeesSortData(user.user.uid))
      if (!ACCOUNTS_SORT_BY && !ACCOUNTS_SORT_ORDER)
        dispatch(getAccountsSortData(user.user.uid))
      goToMain()
      setTimeout(() => {
        dispatch({
          type: 'user_signedin',
          payload: user
        })
      }, 100);
    }
    catch (err) {
      dispatch({
        type: 'auth_error',
        payload: err.toString()
      })
    }
  }

Эта функция выдает ошибку, если что-то пошло не так в процессе входа. Проблема заключается в , когда соединение inte rnet медленное , процесс входа в систему занимает много времени до успеха или сбоя, иногда около 30 секунд, что очень плохо для пользователя.

Вопрос:

Как я могу выдать ошибку через иногда, может быть, 10 секунд, если процесс входа не завершается?

Спасибо!

1 Ответ

0 голосов
/ 17 апреля 2020

Как правило, это может быть достигнуто с помощью setTimeout.

componentDidMount() {
  this.setTimeout( () => {
     this.doThisAfterTenSeconds();
  },10000);
}

doThisAfterTenSeconds() {
   // Do something
}

В этом конкретном сценарии

export const userSignin = (email, password) =>
  async dispatch => {
    try {
      // Auth attempt has started
      dispatch({ type: 'auth_attempt_started' })

      // Lets add a 10 second timeout
      let hasTimedOut = false
      setTimeout(() => {
          hasTimedOut = true
          // Display message here or throw "Connection timed out"
      }, 10000)

      // Now lets await the authentication
      const user = await firebase.auth().signInWithEmailAndPassword(email.trim(), password)
      // This code should not be run if auth attempt timed out. If we throw an error the check should not be neccessary...
      if (!hasTimedOut)
      {
         saveUserDataToAsyncStorage(user)
         if (!TASKS_SORT_BY && !TASKS_SORT_ORDER)
           dispatch(getTasksSortData(user.user.uid))
         if (!EMPLOYEES_SORT_BY && !EMPLOYEES_SORT_ORDER)
           dispatch(getEmployeesSortData(user.user.uid))
         if (!ACCOUNTS_SORT_BY && !ACCOUNTS_SORT_ORDER)
           dispatch(getAccountsSortData(user.user.uid))
         goToMain()
         setTimeout(() => {
           dispatch({
             type: 'user_signedin',
             payload: user
           })
         }, 100);
         }
       }
       catch (err) {
         dispatch({
           type: 'auth_error',
           payload: err.toString()
         })
       }
     }
...