Ответ 1
Два метода могут выглядеть похожими и вести себя одинаково, но fromCallable
справляется с трудностями противодавления для вас, тогда как версия create
не работает. Работа с противодавлением внутри реализации OnSubscribe
варьируется от простого до прямого разума; однако, если опустить, вы можете получить MissingBackpressureException
вдоль асинхронных границ (например, observeOn
) или даже на границах продолжения (например, concat
).
RxJava пытается обеспечить надлежащую поддержку прочного давления для как можно большего количества фабрик и операторов, однако есть немало заводов и операторов, которые не могут его поддерживать.
Вторая проблема с ручной реализацией OnSubscribe
- отсутствие поддержки отмены, особенно если вы создаете много вызовов onNext
. Многие из них могут быть заменены стандартными методами factory (например, from
) или вспомогательными классами (такими как SyncOnSubscribe
), которые справляются со всей сложностью для вас.
Вы можете найти множество примеров и примеров, которые (по-прежнему) используют create
по двум причинам.
- Гораздо проще вводить потоковые потоки данных на основе push, показывая, как толчок событий работает императивно. На мой взгляд, такие источники тратят слишком много времени на
create
пропорционально, вместо того, чтобы говорить о стандартных методах factory и показывая, как можно безопасно выполнять определенные общие задачи (например, ваши). - Во многих из этих примеров было создано время, в течение которого RxJava не требовал поддержки обратного давления или даже надлежащей поддержки синхронной отмены или просто был перенесен из примеров Rx.NET(которые на сегодняшний день не поддерживают противодавление и синхронное аннулирование как-то, любезно из С#, я думаю.) Генерация значений путем вызова onNext была беззаботной. Однако такое использование приводит к раздуванию буфера и чрезмерному использованию памяти, поэтому команда Netflix придумала способ ограничить использование памяти, потребовав от наблюдателей указать количество элементов, которые они готовы продолжить. Это стало известно как противодавление.
Во втором вопросе, а именно, если нужно создать список или последовательность значений, это зависит от вашего источника. Если ваш источник поддерживает некоторую итерацию или потоковую обработку отдельных элементов данных (например, JDBC), вы можете просто подключить их и испустить один за другим (см. SyncOnSubscribe
). Если он не поддерживает его или вам все равно в форме List, то сохраните его как есть. Вы можете всегда конвертировать между двумя формами через toList
и flatMapIterable
, если это необходимо.