- в репозитории прошлого задания сделать новую ветку
- решить предложенный набор задач (и покрыть их тестами от 50%)
- открыть PR с релеватными изменениямяи (без лишних задач)
- сделать ревью 1 PR другого студента
Вам необходимо написать функцию promisify, которая преобразует функцию с колбэком в функцию, возвращающую промис. Это позволит работать с асинхронными функциями в современном стиле, используя промисы вместо колбэков.
Требования:
- Функция promisify принимает на вход функцию, которая ожидает колбэк последним аргументом. Колбэк должен иметь стандартный вид: callback(error, result).
- promisify возвращает новую функцию. При вызове эта функция возвращает промис, который:
- Резолвится с результатом, если в колбэк передан null или undefined вместо ошибки.
- Реджектится, если в колбэк передана ошибка.
- Ваша функция должна корректно передавать все аргументы исходной функции, кроме колбэка.
// Пример функции на колбэках
function sum(a, b, cb) {
setTimeout(() => {
if (Math.random() < 0.5) {
cb(null, a + b); // успех
} else {
cb("Ошибка"); // ошибка
}
}, 100);
}
// Преобразуем с помощью promisify
const promisifiedSum = promisify(sum);
promisifiedSum(2, 3)
.then((result) => console.log(result)) // 5
.catch((err) => console.log(err)); // "Ошибка"Реализуйте класс Parallel, который позволяет запускать несколько асинхронных задач (job) параллельно с ограничением на максимальное количество одновременно выполняющихся задач.
Требования:
-
Класс должен называться
Parallelи быть конструктором (использоваться черезnew). -
У экземпляра должны быть публичные методы:
job(fn)— добавляет задачу (функцию), которую нужно выполнить. Метод должен поддерживать чейнинг (возвращать сам объект).done(cb)— запускает выполнение всех добавленных задач. Когда все задачи завершены, вызывает колбэкcb, передавая ему массив результатов.
-
Если не было добавлено ни одной задачи,
doneдолжен вызываться асинхронно. -
Пока не вызван
done, задачи не запускаются. -
Если при создании объекта передать число (например,
new Parallel(3)), оно задаёт максимальное количество задач, которые могут выполняться одновременно. -
Все задачи — функции, которые принимают один аргумент: функцию-колбэк
done(result), которую нужно вызвать по завершении задачи. -
Результаты должны возвращаться в том же порядке, в котором были добавлены задачи.
-
Продумайте выполнение задач без простоев
const runner = new Parallel(2);
runner
.job((done) => setTimeout(() => done("A"), 1000))
.job((done) => setTimeout(() => done("B"), 500))
.job((done) => setTimeout(() => done("C"), 300))
.done((results) => {
console.log(results); // ['A', 'B', 'C']
});Реализуйте функцию fetchRetry, которая выполняет HTTP-запрос по заданному URL с помощью fetch и автоматически повторяет попытку в случае ошибки. Функция должна принимать три аргумента:
url— строка с адресом запроса.retries— максимальное количество попыток (включая первую).delay— задержка (в миллисекундах) между повторными попытками.
Если запрос завершается успешно, функция возвращает результат как обычный fetch. Если все попытки завершились неудачно, функция должна вернуть ошибку.
fetchRetry("https://dummyjson.com/products", 3, 1000)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Ошибка после всех попыток:", error));Требования:
- Если запрос завершился с ошибкой (например, сеть недоступна или получен некорректный HTTP-статус), функция должна подождать указанную задержку и попробовать снова, пока не исчерпает все попытки.
- После успешного ответа функция должна вернуть результат без дополнительных попыток.
- Если все попытки неудачны, функция должна вернуть ошибку.
Напишите функцию debounce, которая принимает два аргумента:
- функцию, которую нужно вызывать (например, обработчик событий)
- время задержки в миллисекундах
Функция debounce должна возвращать новую функцию-обёртку. Эта обёртка при каждом вызове не будет сразу запускать исходную функцию, а будет откладывать её выполнение на заданное количество миллисекунд. Если обёртку вызвать ещё раз до истечения задержки, предыдущий таймер отменяется и запускается новый отсчёт. В итоге исходная функция будет вызвана только один раз — спустя указанное время после последнего вызова обёртки
function onInput(event) {
console.log("Запрос к серверу:", event.target.value);
}
const debouncedOnInput = debounce(onInput, 500);
inputElement.addEventListener("input", debouncedOnInput);В этом примере функция onInput будет вызываться только через 500 мс после того, как пользователь прекратил вводить текст, а не на каждое нажатие клавиши.
Что проверить:
- Исходная функция вызывается не чаще одного раза за указанный интервал времени.
- При частых вызовах обёртки исходная функция не запускается, пока не наступит "пауза".
- Аргументы и контекст (
this) корректно передаются в исходную функцию.
Напишите функцию serialProcess, которая принимает массив элементов и функцию-обработчик для каждого элемента. Обработчик должен вызываться для каждого элемента массива по очереди (строго по одному, не параллельно), и переходить к следующему элементу только после завершения обработки предыдущего.
Функция-обработчик вызывается с четырьмя аргументами:
el— текущий элемент массива,index— индекс текущего элемента,list— исходный массив,done— функция, которую нужно вызвать по завершении обработки элемента, передав ей результат обработки.
Функция serialProcess должна возвращать промис, который резолвится после завершения обработки всех элементов, с массивом результатов в том же порядке, что и исходный массив.
serialProcess([1, 2, 3, 4, 5], (el, index, list, done) => {
console.log(`${el} start`);
setTimeout(() => {
console.log(`${el} end`);
done(el * el);
}, el * 100);
}).then((list) => console.log(list)); // [1, 4, 9, 16, 25]Требования:
- Каждый элемент обрабатывается только после завершения предыдущего.
- Обработчик может быть асинхронным (например, содержать
setTimeout). - Результаты собираются в массив в том же порядке, что и исходные элементы.
- После обработки всех элементов промис резолвится с массивом результатов.
Домашнее задание ""Принято"" при наборе 3 и более баллов, иначе ""На доработку"".
- Создан и настроен новый репозиторий (пустой первый коммит, линтервы, тесты, пайплайны) , решены задачи, покрытие тестами от 50% - 3 балла
- Покрытие тестами от 70% - +1 балл
- Сделано ревью 1 PR другого студента с 5+ комментариями - +1 балл
Максимальный балл - 5.