В чем смысл AsyncSubject в RXJS?

Документация для RxJS определяет AsyncSubject следующим образом:

AsyncSubject — это вариант, в котором наблюдателям отправляется только последнее значение выполнения Observable и только после завершения выполнения.

Я не понимаю, где/почему мне когда-либо понадобится использовать этот вариант темы. Может ли кто-нибудь дать объяснение или реальный пример, чтобы проиллюстрировать, почему он существует и его преимущества?


person Code Whisperer    schedule 17.01.2018    source источник
comment
AsyncSubject существует для облегчения реализации publishLast . Возможно, проще увидеть вариант использования для этого?   -  person cartant    schedule 17.01.2018
comment
Я собирался написать ответ на этот вопрос, но написал эту статью Вместо этого.   -  person cartant    schedule 02.02.2018
comment
@cartant Это превосходно! Но чтобы это был ответ, который я могу принять, он должен быть ответом с содержанием сообщения в блоге. Все равно спасибо!   -  person Code Whisperer    schedule 05.02.2018
comment
Кто называет эти вещи! :-/   -  person Simon_Weaver    schedule 06.01.2019
comment
Есть ли реальный сценарий для этого?   -  person Ankit Sharma    schedule 06.04.2020


Ответы (2)


Похоже, что это может быть полезно для выборки и кэширования (одноразовых) ресурсов, поскольку обычно http.get выдает один ответ, а затем завершается.

Из rxjs/spec/subjects/AsyncSubject-spec.ts< /а>

it('должно выдавать последнее значение при завершении', () => {
it('должно выдавать последнее значение при подписке после завершения', () => {
it('должно продолжать выдавать последнее значение для последующих подписок', () => {

Компоненты, которые подписываются после выборки, получат значение, чего нельзя сказать о Subject.

const subject = new Rx.Subject();
const asyncSubject = new Rx.AsyncSubject();

// Subscribe before
subject.subscribe(x => console.log('before complete - subject', x))
asyncSubject.subscribe(x => console.log('before complete - asyncSubject', x))

subject.next('value 1');
subject.complete();
subject.next('value 2');

asyncSubject.next('value 1');
asyncSubject.complete();
asyncSubject.next('value 2');

// Subscribe after
subject.subscribe(x => console.log('after complete - subject', x))
asyncSubject.subscribe(x => console.log('after complete - asyncSubject', x))
.as-console-wrapper { max-height: 100% ! important; top: 0 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>

person Richard Matsen    schedule 18.01.2018
comment
Вау, отличный ответ! Действительно помогает объяснить вещи - person Code Whisperer; 18.01.2018
comment
Таким образом, единственная разница между этим и ReplaySubject(1) будет заключаться в том, что ReplaySubject ничего не выдает, пока не завершится? Итак, если вам нужно только одно значение, вы бы использовали AsyncSubject? (не цитируйте меня по этому поводу!) - person Simon_Weaver; 06.01.2019
comment
ReplaySubject испускается всякий раз, когда получает новое значение. AsyncSubject выдает только свое последнее значение, когда видит complete. - person Richard Matsen; 06.01.2019

Прохладно!

И просто для удовольствия я добавил обработчики для регистрации завершенных событий, чтобы показать, что они возникают в любом случае (Subject или AsyncSubject), когда подписка происходит после завершения темы.

Также добавлен BehaviorSubject.

const subject = new Rx.Subject();
const asyncSubject = new Rx.AsyncSubject();
const behaviorSubject = new Rx.BehaviorSubject();

console.log('before init - behaviorSubject', behaviorSubject.value)

subject.next('INIT');
asyncSubject.next('INIT');
behaviorSubject.next('INIT');

console.log('before subscribe - behaviorSubject', behaviorSubject.value)

// Subscribe before
subject.subscribe(x => console.log('before complete - subject', x))
asyncSubject.subscribe(x => console.log('before complete - asyncSubject', x))
behaviorSubject.subscribe(x => console.log('before complete - behaviorSubject', x))

subject.next('NEXT');
subject.complete();

asyncSubject.next('NEXT');
asyncSubject.complete();

behaviorSubject.next('NEXT');
behaviorSubject.complete();

// Subscribe after
subject.subscribe({
  next: x => console.log('after complete - subject', x),
  complete: () => console.log('after complete - subject COMPLETE')
})
asyncSubject.subscribe({
  next: x => console.log('after complete - asyncSubject', x),
  complete: () => console.log('after complete - asyncSubject COMPLETE')
})
behaviorSubject.subscribe({
  next: x => console.log('after complete - behaviorSubject', x),
  complete: () => console.log('after complete - behaviorSubject COMPLETE')
})
.as-console-wrapper { max-height: 100% ! important; top: 0 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.js"></script>

person Christopher King    schedule 27.04.2019