Разница между .unsubscribe для .take(1)

Интересно, есть ли разница в производительности между использованием .take(1) и .unsubscribe когда unsubscribe используется сразу после подписки:

var observable = Rx.Observable.interval(100);

Первый:

var subscription = observable.subscribe(function(value) {
   console.log(value);
}).unsubscribe();

Во-вторых:

var subscription = observable.take(1).subscribe(function(value) {
    console.log(value);
});

Есть ли какие-то идеи по этому поводу?

Ответ 1

Каждый из них преследует разные цели, поэтому их сложно сравнивать.

В общем, если вы берете этот источник:

const source = range(1,3);

... и использовать его с subscribe() а затем сразу же unsubscribe():

source.subscribe(
  console.log,
  undefined, 
  () => console.log('complete')
).unsubscribe();

... тогда все значения из source будут отправлены, даже если мы вызвали unsubscribe() сразу после подписки. Это потому, что код все еще строго последовательный (синхронный), а source - холодная наблюдаемая.

1
2
3
complete

Кстати, попробуйте добавить оператор delay(0) чтобы сделать source.pipe(delay(0)).subscribe(...).unsubscribe(). Это делает выдачу значений асинхронными с использованием фактического вызова setTimeout() и по этой причине unsubscribe() вызывается перед любыми next обработчиками и немедленно отбрасывается.

Другими словами, unsubscribe() позволяет вам прекратить получать значения в любое время. Даже если источник не выдал никакого значения (мы никогда не получим полное уведомление).

Использование оператора take() ограничивает цепочку только определенным числом значений.

source.pipe(
  take(1),
)
.subscribe(
  console.log,
  undefined,
  () => console.log('complete')
);

Это просто излучает одно значение и завершает:

1
complete

Даже если вы добавите .unsubscribe() результат будет таким же.

Смотрите живую демонстрацию: https://stackblitz.com/edit/rxjs-tbu5kb

Так что take() - это оператор, а unsubscribe() - это метод объекта Subscription. Эти две вещи часто взаимозаменяемы, но они никогда не заменяют друг друга полностью.

Январь 2019: обновлено для RxJS 6

Ответ 2

Просто помните, что take (1) по-прежнему не отписывается, когда компонент уничтожается. Подписка остается активной, пока не будет выбрано первое значение, независимо от того, активен компонент или уничтожен. Так что, если мы сделаем что-то более сумасшедшее, например, получим доступ к DOM в нашей подписке - мы можем получить ошибку в консоли. https://blog.angularindepth.com/the-best-way-to-unsubscribe-rxjs-observable-in-the-angular-applications-d8f9aa42f6a0