Повторная попытка неудачной асинхронной функции / обещания?

У меня есть асинхронный блок:

test().then(function(result){
    // Success: Do something.
    doSomething();
}).catch(function(error){
    // Error: Handle the error, retry!
    // How to re-run this whole block?
});

Я могу отслеживать результаты success и failed. Однако можно ли повторить попытку всей цепочки test().then().catch() в случае неудачи? И продолжать попытки, пока проблема не исчезнет?

Поместите это в функцию. Назови это.

Bergi 30.12.2018 23:46

Обратите внимание, что вы должны установить ограничение на частоту повторных попыток или даже задержку отката, чтобы вы не попали в бесконечный цикл и, возможно, не перегрузили любой ресурс в test или doSomething, который выходит из строя.

Bergi 30.12.2018 23:48

Например, используя setTimeout()?

mbilyanov 30.12.2018 23:49

Да, что-то такое

Bergi 30.12.2018 23:59
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
4
6 612
4

Ответы 4

Вы можете поместить все это в функцию, которая рекурсивно вызывает себя, если вводится блок catch:

function tryTest() {
  return test().then(function(result) {
    // Success: Do something.
    doSomething();
  }).catch(function(error) {
    // error handling

    // make sure to return here,
    // so that the initial call of tryTest can know when the whole operation was successful
    return tryTest();
  });
}


tryTest()
  .then(() => {
    console.info('Finished successfully');
  });

Если ваш doSomething может принимать аргумент result, и если tryTest не принимает никаких аргументов, вы можете упростить приведенное выше до:

function tryTest() {
  return test()
    .then(doSomething)
    .catch(tryTest);
}


tryTest()
  .then(() => {
    console.info('Finished successfully');
  });

Вы можете поместить это в функцию.

function dbug() {

test().then(function(result){
    // Success: Do something.
    doSomething();
}).catch(function(error){
    // Error: Handle the error, retry!
    dbug()
});
}

Если вы можете переключиться на синтаксис async/await, вы можете использовать цикл while:

let keepTrying;

do {
    try {
        await test();
        keepTrying = false;
    } catch {
        keepTrying = true;
    }
} while (keepTrying)

doSomething();

Затем вы можете абстрагировать логику повторных попыток в ее собственную функцию для повторного использования.

Предполагая, что все дело в повторной отправке запроса на какой-то ошибочный / раздутый сторонний API

Если это производственный вопрос, скорее, образовательный, я бы предложил поискать стороннюю библиотеку, которая реализует это самостоятельно.

Скажем, для axios есть хороший axios-retry.

Почему? Предположим, вы можете подумать, что есть только один случай, когда API говорит, что возвращает 502. Но на самом деле случаев гораздо больше, о чем лучше помнить:

  1. различные причины ошибки, скажем, если есть ошибка поиска в сети или DNS, может не потребоваться повторный запрос
  2. ограничение количества повторов
  3. увеличивающаяся задержка
  4. что-то другое

Самостоятельно написать такую ​​логику было бы излишним. И попытка использовать самое простое решение может поразить вас, когда вы этого не ожидаете.

PS также в качестве бонуса вы сможете настроить все запросы к определенному API с помощью одного фрагмента, как это происходит для пользовательских экземпляров axios (и я считаю, что должны быть другие плагины для альтернативных библиотек)

Другие вопросы по теме