Нет тайм-аута при вызове второго вызова - PullRequest
0 голосов
/ 01 ноября 2019

У меня есть страница входа в React-Native. Это работает нормально, если у меня есть подключение к Интернету, но теперь я хочу обработать случай, когда Интернет (или сервер) не работает. Я хочу сделать это, используя тайм-ауты: приложение должно попытаться подключиться, и если в течение пяти секунд ничего не получится, я хочу напечатать сообщение об ошибке.

Я сделал это, используя следующий кодвзято из здесь :

export function timeout(
  promise,
  message = 'Request timeout',
  timeout = DEFAULT_TIMEOUT,
) {
  return new Promise((resolve, reject) => {
    const timeoutId = setTimeout(() => {
      console.log('timeout called');
      reject(new Error(message));
    }, timeout);
    promise.then(
      response => {
        clearTimeout(timeoutId);
        resolve(response);
      },
      err => {
        console.log('timeout NOT called');
        clearTimeout(timeoutId);
        reject(err);
      },
    );
  });
}

На странице входа мы называем это так:

response = await timeout(
   getAccessToken(this.state.username, this.state.password),
  'Unable to connect to the server.',
);

, где getAccessToken - асинхронная оболочка вокруг fetch. Он отлично работает при первой попытке входа в систему (с отключенным Интернетом). Он ждет пять секунд (DEFAULT_TIMEOUT) и затем выводит сообщение об ошибке «Невозможно подключиться к серверу». Проблема в том, что если я нажму кнопку входа в систему второй раз, приложение не будет ждать пять секунд и напечатает общую «Сетевую ошибку». Мы видим проблему в logkitty:

[12:08:44] I | ReactNativeJS ▶︎ timeout called                (first click)
[12:08:49] I | ReactNativeJS ▶︎ timeout NOT called            (second click)

Я не понимаю, почему при второй попытке входа тайм-аут не срабатывает и timeout автоматически завершается неудачей. В чем проблема и как ее исправить?

1 Ответ

0 голосов
/ 01 ноября 2019

Promise объекты, возвращаемые из fetch(), равны rejected, когда произошел сбой в сети или запрос не был выполнен.

Если произошла ошибка сети или неправильно настроен CORS на стороне сервера, импорт() встреча отклоняется TypeError, поэтому вторая попытка распознает TypeError и сразу перейдет в состояние отклонения.

Чтобы снова выполнить тайм-аут, необходимо запустить функцию fetch() после подключенияИнтернет. Затем необходимо снова отключить Интернет и запустить fetch()

ПРИМЕЧАНИЕ. Объекты Promise, возвращаемые функцией fetch (), не отклоняют состояние ошибки HTTP. Даже если код состояния HTTP возвращает 404 или 500.

...