Можно ли запустить request B первым если он ни от кого не зависит
Что проверяют
Понимаете ли вы, что порядок запросов определяется зависимостями по данным, а не порядком строк в коде. Интервьюер ждёт, что вы запустите независимые запросы параллельно и объясните, как собрать результаты. Следом спрашивают, что будет, если один из запросов упадёт.
Как отвечать
Да. Если B не ждёт данных от A, его можно стартовать сразу, одновременно с A. Удобно представить запросы графом: всё без входящих зависимостей стартует сразу, зависимые ждут только тех, от кого зависят. Общее время тогда равно самой длинной цепочке, а не сумме всех запросов.
На корутинах это выглядит так: coroutineScope { val a = async { api.loadA() }; val b = async { api.loadB() }; render(a.await(), b.await()) }.
Детали, которые стоит назвать:
- main-safety: suspend-функции Retrofit сами уходят с главного потока, отдельный
withContext(Dispatchers.IO)для них не нужен; - ошибки: в
coroutineScopeпадение одногоasyncотменяет остальные. Если B должен показаться даже при ошибке A, используйтеsupervisorScopeи ловите исключение у каждогоawait; - скоуп:
viewModelScope, а неGlobalScope, чтобы запросы отменились вместе с экраном; - RxJava:
Single.zip(a, b, ...)работает параллельно, только если у каждого источника свойsubscribeOn(Schedulers.io()). Иначе подписка идёт последовательно; - Flow:
combineдля потоков, которые обновляются независимо.
Помните, что «запустить первым» не значит «получить первым». Сеть не гарантирует порядок, поэтому состояние экрана собирайте так, чтобы оно не зависело от того, кто ответил раньше. Есть и ограничения: Dispatcher в OkHttp по умолчанию пропускает не больше 5 одновременных запросов на один хост, остальные ждут в очереди.
Где спотыкаются
Пишут async { a() }.await() и сразу следующий async { b() }.await(). Это последовательный код в обёртке, выигрыша никакого.
Предлагают AsyncTask. Он объявлен устаревшим в API 30, в новом коде его быть не должно.
Не думают о частичном успехе. Экран либо падает целиком из-за второстепенного запроса, либо затирает свежие данные ответом, который пришёл позже.