Наблюдаемый экземпляр излучает без наблюдателя (или подписчика?)

#javascript #angular #rxjs #observable #rxjs5

#javascript #angular #rxjs #наблюдаемый #rxjs5

Вопрос:

Я использую observable в Angular2. Насколько я знаю до сих пор, каждый наблюдаемый экземпляр поставляется с наблюдателем (1: 1), и когда мы выдаем что-либо с observer.next (значение), мы можем получить это значение с помощью observable.subscribe((значение) => {}).

 var observable = Observable.create(observer => {
  observer.next(value);
}
.map(value=>{})
.catch(...)
observable.subscribe(value => {
  console.log(value);
})  

Как я могу выдать значение, не зная соответствующего наблюдателя, потому что я хочу выдать значение вне функции create. Одно из возможных решений — сохранить observer в некоторой глобальной переменной, но я думаю, что наблюдаемого должно быть достаточно. Есть предложения по этому поводу??

Комментарии:

1. Возможно, вы ищете что-то вроде Subject ?

2. О, похоже, это можно сделать, используя Subject вместо Observable, большое вам спасибо!! Мне потребуется время, чтобы рассмотреть это подробнее. Или я думаю, может быть, я могу создать класс, делающий то, что мне нужно 🙂

3. Тема — это путь, которым нужно идти. Также обратите внимание, что это не соотношение 1: 1, вы можете подписаться несколько раз

4. О, моя ошибка, я думал, что каждый раз, когда мы подписываемся, есть только один наблюдатель, но оказывается, что каждая подписка создает одного другого наблюдателя. Ужасное недоразумение ><!!

5. Действительно. Subject — это тот, который вам нужно использовать. Это эквивалентно q.defer() в angular 1. Затем в вашей функции вы возвращаете subject, который равен defer.promise. Также defer.reject = subject.error(), subject.next= defer.resolve

Ответ №1:

Вы смешиваете несколько вещей вместе. Наблюдаемые объекты не находятся в соотношении 1: 1 с наблюдателями (точнее, это 1: N). Если вы хотите иметь возможность вручную генерировать значения, вам нужен Subject который действует как наблюдаемый и наблюдатель одновременно. Практически это означает, что вы можете вызвать его next() метод, и он передаст значение всем своим подписчикам (наблюдателям).

Для примера рассмотрим следующий код в TypeScript:

 import {Subject} from 'rxjs';

let source = new Subject();

source.subscribe(val => console.log('Observer 1:', val));
source.subscribe(val => console.log('Observer 2:', val));

source.next(42);
source.next('test');
  

Это выведет на консоль:

 Observer 1: 42
Observer 2: 42
Observer 1: test
Observer 2: test
  

Смотрите живую демонстрацию: http://plnkr.co/edit/gWMFMnPlLJVDC1pQi8pH?p=preview

Подробнее:

Имейте в виду, что Observable.create() это совсем другое животное. Он принимает в качестве параметра функцию, которая вызывается каждый раз, когда подписывается новый Наблюдатель. Вот почему он принимает вновь подписанного наблюдателя в качестве аргумента. В этой функции вы можете, например, вызвать next() метод наблюдателя, чтобы отправить ему некоторое значение по умолчанию, которое должны получать все подписчики.

Поэтому вы, вероятно, хотите использовать Subject вместо Observable.create() .

Комментарии:

1. Спасибо за ваш подробный ответ, но немного больше смущает, что я могу использовать map операцию с Subject

2.@dttung1412 Конечно, вы можете. Subject расширяется Observable , поэтому в нем есть все операторы как Observable reactivex.io/rxjs/class/es6/Subject.js ~Subject.html