Передайте результат подписки на onNext - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть функция, которая извлекает некоторую информацию из веб-службы:

const rxjs = require('rxjs');
const request = require('request');
const moment = require('moment');
function getAvailableGroupClasses() {
    return rxjs.Observable.create(observable => {
        request(`https://myservice.com/get.json`, (error, response, body) => {
            const j = JSON.parse(body);
            observable.next(j);
            observable.complete();
        });
    });
}

Возвращает наблюдаемое, которое затем добавляется другой функцией:

function findClassOnDateTime(className, targetDateTime) {
    return rxjs.Observable.create(observable => {
        getAvailableGroupClasses().subscribe(classes => {
            classes.getAllGroupClassesMap
            .filter(value => value.nomeAtividade === className) // filter by name
            .filter(value => moment(`${value.day} ${value.time}`, 'YYYY-MM-DD HH:mm:ss').isSame(momentTargetDateTime, 'minute')) //filter by class date
            .map(values => observable.next(values)) // wrap this in an observable, call here next
        });
    });
}

Наконец, фасад будет называть findClassOnDateTime так:

findClassOnDateTime('classname', moment().day(1 + 7).hour(19).minute(20)).subscribe(values => {
    console.log(values);
});

Моя проблема в функции findClassOnDateTime. Он подписывается на Observable и создает новый для передачи значения. Хотя это работает, я читал в Интернете, что Observables не должны быть связаны или вложены, но я не видел ни одного примера, когда нужно создавать Observable, а не только подписываться на него.

Точно так же, как указать, что фасад не должен вызывать getAvailableGroupClasses, а затем findClassOnDateTime, все это должно быть сделано в findClassOnDateTime.

1 Ответ

0 голосов
/ 27 апреля 2018

Вы можете использовать map, filter и многие другие операторы непосредственно на observable. На самом деле вы переопределяете оператор map каждый раз, когда создаете новую наблюдаемую.

Я предполагаю, getAllGroupClassesMap это массив. Вы можете преобразовать массив в наблюдаемый с помощью Observable.from и объединить все операторы в цепочку.

function createHttpObservable(url) {
   return Observable.create(observer => {
      request(url, (error, response, body) => {
         const j = JSON.parse(body);
         observer.next(j);
         observer.complete();
      });
   });
}

function findClassOnDateTime(className, targetDateTime) {
   return createHttpObservable("https://myservice.com/get.json").concatMap(r => Observable.from(r.getAllGroupClassesMap))
      .filter(value => value.nomeAtividade === className)
      .filter(value => moment(`${value.day} ${value.time}`, 'YYYY-MM-DD HH:mm:ss').isSame(targetDateTime, 'minute'));
}

findClassOnDateTime("..." , xxxx).subscribe(values =>  console.log(values));
...