Постраничная загрузка через асинхронный генератор
Вопрос
Как бы вы реализовали перебор всех записей постраничного API так, чтобы вызывающий код просто писал for await (const item of allItems())?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
`async function*`, внутри цикл по страницам с `await fetch`
`yield*` по элементам страницы или `yield` поштучно
Условие остановки: нет курсора `next` или пустая страница
Ленивость: следующая страница грузится только когда потребитель дошёл до конца текущей
Досрочный `break` у потребителя завершает генератор, запросы прекращаются; `finally` для очистки
Ошибки и отмена: `try/catch` у потребителя, `AbortSignal` в параметрах
Что могут спросить следом
- Как подгружать следующую страницу заранее, пока обрабатывается текущая?
- Что будет, если потребитель бросит исключение в теле цикла?
- Как ограничить общее число записей?
Разбор
Образцовый ответ: «Делаю асинхронный генератор allItems(signal). Внутри держу курсор, в цикле while запрашиваю страницу через await fetch(url, { signal }), разбираю JSON и делаю yield* page.items, чтобы потребитель получал записи поштучно. Если в ответе нет курсора следующей страницы, цикл заканчивается. Важное свойство: генератор ленивый, следующая страница запрашивается, только когда потребитель дочитал текущую, а если он сделал break, for await вызовет у генератора return, выполнится мой finally, и больше запросов не будет. Ошибки сети всплывут как исключение в цикле потребителя, он их ловит обычным try/catch. Отмену прокидываю через AbortSignal. Если хочется скорости, можно запрашивать следующую страницу заранее: запускаю промис следующего запроса до yield* текущих элементов и жду его после. Ограничить количество можно счётчиком у потребителя или параметром limit в самом генераторе: асинхронных iterator helpers в стандарте пока нет».
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.