Продавец Ozon загружает в карточку 15 фотографий. Если отправить все сразу, браузер упрётся в лимит соединений, а сервер вернёт 429. Нужно не больше limit загрузок одновременно.
Напишите runWithLimit(tasks, limit). tasks — массив функций, каждая возвращает промис. Как только одна загрузка закончилась, сразу стартует следующая по порядку — не ждём всю пачку. Результат — массив в порядке tasks.
При первой ошибке итоговый промис отклоняется ею, новые задачи больше не запускаются. Пустой массив — сразу [].
В работе: Загрузка файлов, массовые запросы к API с лимитом, предзагрузка картинок.
Пример 1: следующая сразу после любой
[[300, true], [100, true], [200, true], [100, true]], 2
{"out": {"at": 400, "ok": true, "value": ["фото1", "фото2", "фото3", "фото4"]}, "peak": 2, "starts": [[0, 0], [1, 0], [2, 100], [3, 300]]}Пример 2: лимит больше числа задач
[[100, true], [50, true]], 5
{"out": {"at": 100, "ok": true, "value": ["фото1", "фото2"]}, "peak": 2, "starts": [[0, 0], [1, 0]]}runWithLimit — тест вызывает её сам. Таймеры и Date в тестах ненастоящие: время идёт по команде теста, поэтому setTimeout на 5 секунд проверяется мгновенно. Тестов 6: 2 открыты выше, остальные приходят после старта подхода. Лимит — 2 с на тест.
function runWithLimit(tasks, limit) // → Promise<Array>
Источник: на задачах Ozon: кабинет продавца, загрузка фото. Условие пересказано своими словами.
Ожидаемый ответ не нужен: покажем, что вернула функция.
Здесь появится результат отправки.