Реализация резина
Иногда вы должны быть в состоянии повторить операцию несколько раз, пока она не удастся (или сдавайся после нескольких попыток). Есть много способов реализации этого.
В качестве основания давайте будем использовать функцию под названием пауза
позволяя вам ждать некоторое время между вашими попытками:
function pause(delay = 100) { return new Promise(resolve => setTimeout(resolve, delay)) }
Старый добрый для петли
Теперь простой подход для реализации ре более что будет использоваться классический для цикла:
async function retrier(operation, { attempts = Infinity, delay = 100 }) for (let i = 0 ; i < maxAttempts ; i++) { const result = await operation() if (result) return result await pause(delay) }
Тогда вы можете использовать по очереди таким образом:
const result = await retrier( () => tryOperation(), { attempts: 5, delay: 500 } )
Как это работает, есть несколько вещей, которые мне не нравятся с таким подходом:
- У вас мало контроля над тем, что происходит внутри цикла для цикла (Сколько времени нужно было добиться успеха?)
- Вы должны пройти операцию в качестве параметра, который, я думаю, чувствую себя немного странно
- Любая пользовательская логика вам понадобится выполнить в цикле (например, если у вас есть несколько операций) придется попасть в
Tromoperation
функция
Конечно, вы можете избежать создания ringer
Функция и просто дублировать это для цикла везде. Но с более сложным кодом внутри цикла или с Перерыв
или Продолжить
Заявления, это станет действительно сложным.
Функции генератора
Другим способом реализации этого является использование Async Generator. Но сначала давайте посмотрим, что такое генератор.
Функция генератора – это функция (какой сюрприз), которая возвращает генератор (большое время мозга). Генератор Урожайность
Значения, которые вы можете повторить, используя для
петля, например.
Точка генератора состоит в том, что он может создавать значения, когда они нуждаются в них, вместо того, чтобы построить массив, затем, например, для него. Рассмотрим следующий пример:
// function* is the way to declare a Generator function* count() { let count = 0 // yield allows you to "generate" a value while(true) yield i++ }
Если вы используете этот генератор, вы можете повторить вечно, с количеством, которое увеличивается до бесконечности. Без необходимости создавать все цифры заранее!
for (const index of count()) { console.log(index) }
Асинхронные генераторы
Теперь в чем разница с асинхронным генератором? Хорошо… Это генератор, но async! Это все, что вы должны знать об этом, правда.
Вы объявите его так же, но с Async до Функция
Ключевое слово, то используйте Ждите
в объявлении для цикла.
Вот режерам, реализованный с использованием асинхронизатора:
async function* retrier({ attempts = Infinity, delay = 100 }) { for (let i = 0; i < attempts; i++) { yield i await pause(delay) } }
Теперь, если вы хотите использовать это, все, что вам нужно сделать, это использовать для Loop ange:
for await (const _ of retrier({ attempts: 5, delay: 500 })) { // This gets executed every 500ms // And up to 5 times! const result = await tryOperation() if (result) break }
Столько, сколько я согласен с тем, что он не изменяется «много», я думаю, что этот код легче подходить и разум при сохранении цикла, который мы используем в JavaScript.
Фото Jayphen Simpson на Бессмысленно
Оригинал: “https://dev.to/qmenoret/implement-a-retrier-using-async-generator-3o9n”