Войти Регистрация
Фронтенд

66. Один запрос профиля продавца Авито на десять виджетов

Средняя

На карточке объявления Авито профиль продавца нужен шапке, блоку «Другие объявления продавца», рейтингу и кнопке «Написать». Каждый виджет вызывает getSeller(id) сам, и при открытии карточки уходит 4–10 одинаковых запросов.

Напишите dedupe(fetcher). Результат — функция (key) => Promise. Если по этому ключу запрос уже идёт, вернуть тот же промис, не вызывая fetcher. Иначе вызвать fetcher(key) и запомнить промис.

Когда промис выполнился или отклонился, ключ освобождается: следующий вызов снова идёт в сеть. Ошибку получают все, кто ждал этот запрос. Если fetcher бросил исключение синхронно, вызывающий получает отклонённый промис, а ключ не остаётся занятым.

В работе: Карточка объявления открывается 30 раз в секунду на пике, и каждый лишний запрос профиля — нагрузка на сервис продавцов.

Пример 1: четыре виджета — один запрос

Аргументы теста
[["call", "u42"], ["call", "u42"], ["tick", 50], ["call", "u42"], ["call", "u42"]]
Ожидается
{"fetched": [["u42", 0]], "log": [[100, "продавец u42"], [100, "продавец u42"], [100, "продавец u42"], [100, "продавец u42"]], "firstTwoSame": true}

Пример 2: разные продавцы — разные запросы

Аргументы теста
[["call", "u1"], ["call", "u2"]]
Ожидается
{"fetched": [["u1", 0], ["u2", 0]], "log": [[100, "продавец u1"], [100, "продавец u2"]], "firstTwoSame": false}
Как проверяем Объявите dedupe — тест вызывает её сам. Таймеры и Date в тестах ненастоящие: время идёт по команде теста, поэтому setTimeout на 5 секунд проверяется мгновенно. Тестов 6: 2 открыты выше, остальные приходят после старта подхода. Лимит — 2 с на тест.
function dedupe(fetcher) // → (key) => Promise
промисыMapдедупликация запросов

Источник: на задачах Авито: карточка объявления и профиль продавца. Условие пересказано своими словами.