Я хочу, чтобы JavaScript-код принимал 3 параметра в качестве параметров:
- Функция, возвращающая Обещание.
- Максимальное количество попыток.
- Задержка между каждой попыткой.
Я закончил тем, что использовал цикл for
. Я не хотел использовать рекурсивную функцию: таким образом, даже если есть 50 попыток, стек вызовов не на 50 строк длиннее.
Вот машинопись версия кода:
/**
* @async
* @function tryNTimes<T> Tries to resolve a {@link Promise<T>} N times, with a delay between each attempt.
* @param {Object} options Options for the attempts.
* @param {() => Promise<T>} options.toTry The {@link Promise<T>} to try to resolve.
* @param {number} [options.times=5] The maximum number of attempts (must be greater than 0).
* @param {number} [options.interval=1] The interval of time between each attempt in seconds.
* @returns {Promise<T>} The resolution of the {@link Promise<T>}.
*/
export async function tryNTimes<T>(
{
toTry,
times = 5,
interval = 1,
}:
{
toTry: () => Promise<T>,
times?: number,
interval?: number,
}
): Promise<T> {
if (times < 1) throw new Error(`Bad argument: 'times' must be greater than 0, but ${times} was received.`);
let attemptCount: number;
for (attemptCount = 1; attemptCount <= times; attemptCount++) {
let error: boolean = false;
const result = await toTry().catch((reason) => {
error = true;
return reason;
});
if (error) {
if (attemptCount < times) await delay(interval);
else return Promise.reject(result);
}
else return result;
}
}
Используемая выше функция delay
является многообещающим тайм-аутом:
/**
* @function delay Delays the execution of an action.
* @param {number} time The time to wait in seconds.
* @returns {Promise<void>}
*/
export function delay(time: number): Promise<void> {
return new Promise<void>((resolve) => setTimeout(resolve, time * 1000));
}
Чтобы уточнить: код выше работает , мне только интересно, если это "хороший" способ сделать это, и если нет, как я мог бы улучшить его.
Есть предложения? Заранее спасибо за помощь.