首页 > 解决方案 > 将订阅结果传递给 onNext

问题描述

我有一个从 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
        });
    });
}

最后,façade 会findClassOnDateTime这样调用:

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

我的问题在于功能findClassOnDateTime。它订阅一个 Observable 并创建一个新的来传递值。虽然它正在工作,但我一直在网上阅读 Observables 不应链接或嵌套,但我没有看到任何示例说明何时必须创建 observable 而不仅仅是订阅它。

就像指出façade不应该调用getAvailableGroupClasses然后findClassOnDateTime,它必须全部完成findClassOnDateTime

标签: javascriptnode.jsrxjsobservable

解决方案


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

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

推荐阅读