Коли використовувати asObservable () у rxjs?


84

Мені цікаво, яка користь від asObservable:

Відповідно до документів:

Спостерігається послідовність, яка приховує ідентичність вихідної послідовності.

Але навіщо вам потрібно приховувати послідовність?

Відповіді:


187

Коли використовувати Subject.prototype.asObservable ()

Метою цього є запобігання витоку "сторони спостерігача" Суб'єкта з API. В основному, щоб запобігти негерметичному абстрагуванню, коли ви не хочете, щоб люди могли "наступним чином" потрапляти в отримане спостережуване.

Приклад

(ПРИМІТКА: Це насправді не так, як ви повинні перетворити подібне джерело даних на Observable, замість цього ви повинні використовувати new Observableконструктор, див. Нижче).

const myAPI = {
  getData: () => {
    const subject = new Subject();
    const source = new SomeWeirdDataSource();
    source.onMessage = (data) => subject.next({ type: 'message', data });
    source.onOtherMessage = (data) => subject.next({ type: 'othermessage', data });
    return subject.asObservable();
  }
};

Тепер, коли хтось отримує спостережуваний результат, myAPI.getData()він не може nextоцінювати результат:

const result = myAPI.getData();
result.next('LOL hax!'); // throws an error because `next` doesn't exist

Ти, як правило, повинен використовувати new Observable(), однак

У наведеному вище прикладі ми, мабуть, створюємо щось, чого не мали на меті. По-перше, getData()не ледачий, як більшість спостережуваних, він негайно створить базове джерело даних SomeWeirdDataSource(і, мабуть, деякі побічні ефекти). Це також означає, що якщо ви retryабо repeatспостережуваний результат, це не буде працювати так, як ви думаєте.

Краще інкапсулювати створення джерела даних у межах спостережуваного так:

const myAPI = {
  getData: () => return new Observable(subscriber => {
    const source = new SomeWeirdDataSource();
    source.onMessage = (data) => subscriber.next({ type: 'message', data });
    source.onOtherMessage = (data) => subscriber.next({ type: 'othermessage', data });
    return () => {
      // Even better, now we can tear down the data source for cancellation!
      source.destroy();
    };
  });
}

З наведеним вище кодом будь-яка поведінка, включаючи «не лінивий», може бути складена поверх спостережуваної за допомогою існуючих операторів RxJS.


3
TX Ben ... стежив за твоїми речами ... tx за всю велику підтримку на RX
born2net

3
@Shardul ... ти підписався б на результат:result.subscribe(value => doSomething(value))
Бен Леш

2
@BenTaliadoros Так, кожного разу, коли ви будете, return subject.asObservable();це буде новим спостережуваним. У вас буде одна змінна члена Subject, і onMessage / onOtherMessage буде оголошено в стані або під час ініціалізації (не кожного виклику). Я використав такий підхід, pipe( filter() )базуючись на параметрі, який подається до getData()функції. The
Drenai

5
@BenLesh, у вашому другому зразку коду subjectповинен бути subscriber?
Флорін Д,

1
Я також хотів би перевірити тут: чи мають subject.nextбути рядки subscriber. Крім того, "якщо ви повторите спробу або повторите отримане спостережуване, це не буде працювати так, як ви думаєте". Чи можете ви бути більш конкретними? Ви просто маєте на увазі new SomeWeirdDataSource(), що відбуватиметься кожен раз, коли getDataбуде викликано, і що, загортаючи його, new Observableви змушуєте цей екземпляр чекати, поки підписка. Думаю, я не бачу, коли ви зателефонували б getDataбез a, .subscribeтому я там втрачаю значення. Нарешті, що ви передбачаєте, щоб "зруйнувати джерело даних"? Дякую.
1252748

7

А Subjectможе діяти як як, так observerі як observable.

Ан Obervableмає 2 методи.

  • передплатити
  • відписатися

Щоразу, коли ви підписуєтесь на observable, ви отримуєте метод, observerякий містить наступні , помилки та повні методи.

Вам потрібно буде приховати послідовність, оскільки ви не хочете, щоб джерело потоку було загальнодоступним у всіх компонентах. Ви можете звернутися до @BenLeshприкладу '' для того самого.

PS: Коли я вперше пройшов реактивний Javascript, я не зміг зрозуміти asObservable. Тому що я повинен був переконатися, що я чітко розумію основи, а потім піти далі asObservable. :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.