Батчинг запросов как в DataLoader
Условие
Напиши createLoader(batchFn), где batchFn(keys) асинхронно возвращает массив значений в том же порядке, что и keys. Возвращается функция load(key) => Promise. Все load, вызванные в одном синхронном куске кода (до следующей микрозадачи), склеиваются в один вызов batchFn с уникальными ключами. Повторный ключ в одной пачке не дублируется, оба load получают одно значение. Если batchFn упал, отклоняются все load этой пачки. Если batchFn вернул Error на месте ключа, отклоняется только этот load.
Это решение проблемы N+1 в GraphQL и ORM.
Что проверяют тесты
один вызов batchFn на синхронную пачку
дубли ключей склеиваются
разные тики: разные пачки
падение batchFn отклоняет всю пачку
Error на месте значения отклоняет только свой load
после пачки можно грузить снова
Как подойти
Пачка копится, пока выполняется синхронный код. Отправка в микрозадаче: к этому моменту все load текущего тика уже вызваны.
Подсказки: 2
- Первый
loadв тике создаёт пачку и планирует её отправку черезqueueMicrotask. - Пачка:
Map<key, массив {resolve, reject}>, тогда дубли склеятся сами.
Решите в тренажёре
Редактор с автотестами прямо в браузере. Можно решить спокойно, вслух или под таймером, как на собесе.
Предыдущий вопрос
Cache-aside с отрицательным кешированием
Следующий вопрос
Идемпотентный обработчик по Idempotency-Key