Совет: используйте только first()
если:
- Вы считаете, что ноль отправленных элементов является условием ошибки (например, завершение перед отправкой) И если вероятность ошибки больше 0%, вы правильно ее обрабатываете
- ИЛИ Вы на 100% знаете, что наблюдаемый источник испускает 1+ элементов (поэтому никогда не может выбросить) .
Если выбросы нулевые и вы явно не обрабатываете их (с помощью catchError
), то эта ошибка будет распространяться вверх, возможно, вызовет неожиданную проблему в другом месте, и ее может быть довольно сложно отследить, особенно если она исходит от конечного пользователя.
По большей части вы безопаснее использовать take(1)
при условии, что:
- Вы в порядке,
take(1)
если ничего не испускаете, если источник завершается без эмиссии.
- Вам не нужно использовать встроенный предикат (например
first(x => x > 10)
).
Примечание: Вы можете использовать предикат с take(1)
так: .pipe( filter(x => x > 10), take(1) )
. Это не приведет к ошибке, если ничто не превышает 10.
Что о single()
Если вы хотите быть еще строже и запретить два выброса, вы можете использовать single()
какие ошибки, если выбросы равны нулю или 2+ . В этом случае вам снова придется обрабатывать ошибки.
Совет: Single
иногда может быть полезен, если вы хотите, чтобы ваша наблюдаемая цепочка не выполняла лишнюю работу, например, дважды вызывала http-службу и генерировала две наблюдаемые. Добавление single
на конец трубы сообщит вам, если вы сделали такую ошибку. Я использую его в «средстве выполнения задач», где вы передаете наблюдаемую задачу, которая должна выдавать только одно значение, поэтому я передаю ответ, single(), catchError()
чтобы гарантировать хорошее поведение.
Почему бы всегда не использовать first()
вместо take(1)
?
ака. Как first
потенциально может вызвать больше ошибок?
Если у вас есть наблюдаемый объект, который берет что-то из службы, а затем передает это по first()
конвейеру, в большинстве случаев все будет в порядке. Но если кто-то по какой-то причине придет и отключит службу - и изменит ее на emit, of(null)
иначе NEVER
любые последующие first()
операторы начнут выдавать ошибки.
Теперь я понимаю, что это может быть именно то , что вам нужно, поэтому это всего лишь подсказка. Оператор first
обратился ко мне, потому что это звучало немного менее «неуклюже», чем, take(1)
но вам нужно быть осторожным с обработкой ошибок, если когда-либо есть вероятность того, что источник не будет излучать. Однако все будет зависеть от того, что вы делаете.
Если у вас есть значение по умолчанию (константа):
Также .pipe(defaultIfEmpty(42), first())
подумайте, есть ли у вас значение по умолчанию, которое следует использовать, если ничего не испускается. Это, конечно, не вызовет ошибку, потому first
что всегда будет получать значение.
Обратите внимание, что defaultIfEmpty
запускается только в том случае, если поток пуст, а не в том случае, если значение того, что испускается, равно null
.
first()
иtake()
в целом они такие же, что я думаю, очевидно, только то, чтоfirst()
иtake(1)
такие же. Я не уверен в вашем ответе, считаете ли вы, что разница все еще есть?