Basi c вопрос по rx js наблюдаемым - как передать данные в наблюдаемую «вручную»? - PullRequest
1 голос
/ 29 марта 2020

Я хотел бы использовать наблюдаемое, чтобы сигнализировать различным частям моего Angular приложения об «исключительных состояниях» и аналогично, но я понимаю, что не очень понимаю, как они работают.

В следующем В коде я построил объект-наблюдатель и создал из него наблюдаемый объект. Я хотел бы выяснить, как вызвать метод «next» вне области действия метода Observable.create, чтобы я мог вставить произвольные события в поток. Вызов next прямо на наблюдателя deos, похоже, не является ответом.

 var observer = {
      next: function(value) {
        this.myvalue="last value: " + value;
      },
      error: function(error) {
        console.log(error);
      },
      complete: function() {
        console.log('completed');
      },
      myfunction: function() {
        this.myvalue = "Penguins"
      },
      myvalue: ""
    }

   let myobs$ : Observable<any> = Observable.create(function(obs) {
      obs.next("Some foo");

      obs.next("Other foo");
    })

    let foo=myobs$.subscribe((observer)=> {
      console.log("This is the subscription: ", observer)
    })

    setTimeout(function() {
      observer.next("This is a late breaking value");
      console.log(observer.myvalue);
    }, 2000);

  }

этот код производит следующий вывод на консоль:

This is the subscription:  Some foo
This is the subscription:  Other foo
last value: This is a late breaking value

Так что похоже на вызов next on объект-наблюдатель напрямую (который я пробовал внутри функции тайм-аута внизу) не создает значения внутри подписки.

Также ясно, что я не понимаю, как эти вещи должны работать. Было бы полезно понять, что, если я настроил наблюдаемое и я хочу «вручную» вставить данные в поток, который будет собираться подписчиками, как именно я это сделаю? Я могу видеть, как вы делаете это с помощью таких распространяющих события событий, как щелчки мышью или ajax запросов, но я хочу создать поток, который я могу подавать на ad-ho c основе, когда некоторые интересные вещи случаются в разных местах в моем коде.

Ответы [ 2 ]

2 голосов
/ 29 марта 2020

Вы должны прочитать на Rx Js Subject. Это будет то, что вам нужно. Из документации:

Субъект - это особый тип наблюдаемых, который позволяет многоадресно передавать значения многим наблюдателям. Предметы похожи на EventEmitters.

Существуют разные типы предметов. ReplaySubject, BehaviorSubject, AsyncSubject. Я предлагаю вам погрузиться в документацию или некоторые учебные пособия о том, как и когда их использовать. Из вашей наблюдаемой вы также хотите, чтобы предыдущие значения и новые значения были испущены. Вы можете сделать такое пользовательское поведение с переносимыми операторами, с которыми Rx Js поставляется вместе с . Я предлагаю вам также прочитать о них. Вот еще одна статья о stackoverflow , которая точно делает то, что вы хотите:

На основе этого примера:

const subject = new Subject().pipe(
  startWith('Penguins'), // emitting first value to fill-in the buffer
  pairwise(),
  map([previous, current] => {
    return previous + current;
  }),
);

const observer = {
  next: (value) => {
    console.log(value);
  },
  error: (error) => {
    console.log(error);
  },
  complete: () => {
    console.log('completed');
  },
};

// Subjects
const subscriber = subject.subscribe(observer);

subject.next('Some foo');
1 голос
/ 29 марта 2020

Короче говоря: вы не можете , если вы создаете наблюдаемые таким образом. То, что вы фактически передаете в качестве аргумента метода subscribe(), это просто функция, которая будет вызываться при изменении состояния объекта. Эта функция (и любая другая, потому что вы можете подписаться несколько раз) будет сохранена, поэтому вы должны помнить, чтобы отписаться от нее. Observables - это не более, чем rx js реализация шаблона Observator. Но есть и другой способ подать сигнал, если что-то изменится. Вместо переменных типа number, string et c. Вы можете использовать Subject или BehaviourSubject или даже ReplaySubject, чтобы легко уведомлять об изменении состояния. Subject не хранит значение, которое вы передаете с помощью метода next(), поэтому вы получите только при подписке, прежде чем использовать next(). BehaviourSubject сохранить значение, и когда вы подпишетесь, вы получите последнее значение. ReplaySubject аналогично BehaviourSubject, но будет выдавать n последних значений.

Редактировать: На самом деле вы можете, но вы должны сохранить функцию, которую вы передаете в обратном вызове Observable.create, и вы можете использовать next вне Observable для отправки некоторых данных. Но даже при том, что я настоятельно рекомендую вам использовать Subjects.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...