将订阅结果传递给onNext

时间:2018-04-27 15:32:15

标签: javascript node.js rxjs observable

我有一个从Web服务获取一些信息的函数:

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();
        });
    });
}

它返回一个observable,然后被另一个函数挂起:

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 :(得分:1)

您可以直接在map上使用filterobservable和更多运算符。实际上,每次创建新的observable时,都会重新实现map运算符。

我猜getAllGroupClassesMap是一个数组。您可以使用Observable.from将数组转换为observable并链接所有运算符。

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));