Angular и Http-вызовы Как сделать http-вызов, чтобы продолжать попытки, пока не будет получен успешный ответ? - PullRequest
0 голосов
/ 29 мая 2020

Мы переносим данные из одной системы в другую. Эти данные состоят из двух файлов Excel.

Первый содержит основную / общую информацию о семье, а другой - информацию о каждом члене каждой семьи.

Скрипт состоит двух вложенных циклов. Первый l oop возьмет строку из Excel, добавит ее в базу данных, затем второй l oop будет искать связанных членов (используя уникальный идентификатор для каждой семьи) и также добавлять их.

Я заключил HTTP-вызовы внутрь promise. Когда обещание будет выполнено, мы перейдем к следующему шагу, если нет, в файл журнала будет добавлен массив, в котором будет указано, что в этой строке возникла проблема при загрузке, и мы проверим его позже.

Иногда при обработке HTTP-вызовов от наблюдаемого некоторые из вызовов будут опережать другие, которых не должно быть. Допустим, добавляется семейство X, и выполняется 5 HTTP-вызовов, если один из них получил поздний ответ и начальное l oop началось с загрузки информации семейства Y, код сломается, из-за структуры новой системы, на которую мы переходим.

Короче говоря, при загрузке данных мы получаем ошибку 500: Internal Server Error, не зная причины. Но мы ожидали, что это произойдет, поэтому мы сделали следующее в нашей службе api.services.ts:

postData(data) {
    const url = 'apiUrlForDataUpload';
    return this.http.post(url, data, this.httpOptions).pipe(retry(3), timeout(15000));
}

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

Проблема в том, что всякий раз, когда сервер возвращает ошибку, l oop будет сломан и вызов не будет повторять процесс 1 раз, по крайней мере, не три.

Как сделать HTTP-вызов, чтобы продолжать попытки, пока не будет получен успешный ответ?

Ответы [ 2 ]

2 голосов
/ 29 мая 2020
postData(data) {
  const url = `apiUrlForDataUpload`
  return this.http.post(url, data, this.httpOptions).pipe(retryWhen(err => err.pipe(delay(timer(2000)))));
)
1 голос
/ 29 мая 2020

Можно использовать catchError и retry() (без номера).

        this.httpClient.get('http://doesnot.exist').pipe(
            tap(
                () => console.log('emit'),
                () => console.log('error'),
                () => console.log('complete'),
            ),
            // a short delay in a retry.
            catchError(error => timer(1500).pipe(switchMapTo(throwError(error)))),
            retry(),
        ).subscribe();
...