Angular2 / rxjs:订阅不触发mergeMaps&的Observable表达式forkJoins

时间:2017-05-02 18:56:01

标签: angular rxjs observable

我的服务有一个基本上是:

的方法
this.backend.getJSON(`${name}/book`).mergeMap(
  book => Observable.forkJoin(book.parts.map((partName: string) =>
    this.backend.getJSON(`${name}/${partName}/part`).mergeMap(
      part => Observable.forkJoin(part.sections.map((sectionName: string) =>
        this.backend.getJSON(`${name}/${partName}/${sectionName}/section`).mergeMap(
          section => Observable.forkJoin(section.chapters.map((chapterName: string) =>
            this.backend.getJSON(`${name}/${partName}/${sectionName}/${chapterName}/chapter`).map(chapter => {
              this.transform(chapter.content, `${name}/${partName}/${sectionName}/${chapterName}`);
              return chapter;
            }))),
          this.assignAndReturn('chapters'))),
      this.assignAndReturn('sections'))))),
  this.assignAndReturn('parts'));

(我已经内联 - 稍微简化了 - 一些叫做方法,这就是为什么它是如此巨大的表达,因此在getJSON args中重复。)

assignAndReturn只是:

private assignAndReturn<T1, T2>(name: string) {
  return (a: T1, b: T2) => {
    a[name] = b;
    return a;
  };
}

.subscribe(...)这似乎不起作用。它似乎只是在表达树的中途,而不是“制作它”一直到章节。

我真的不知道发生了什么。这几乎就好像我需要订阅“内部”部分,但外部订阅不会触发......

1 个答案:

答案 0 :(得分:0)

您可以尝试这样的模式,利用flatMap。上一个事件结束后,flatMap将继续使用其回调返回的Observable。它有助于提高可读性,并使您能够在整个过程中监视您的流。

import { Observable } from 'rxjs';

class Demo {
    backend = {
        // Simulated request
        getJSON: (str, demoValue) => Observable.of(demoValue).delay(new Date(Date.now() + 1000))
    }

    getBook(name) {
        this.backend
            // Get the book
            .getJSON(`${name}/book`, name)
            // Get the parts
            .flatMap(book => { 
                // Observable.from() will create an observable event
                // for each item in the array
                return this.backend
                    .getJSON(`[Next URL]`, [`${book}/part1`, `${book}/part2`])
                    .flatMap(parts => Observable.from(parts));
            })
            // Get the sections
            .flatMap(part => {
                return this.backend
                    .getJSON(`[Next URL]`, [`${part}/section1`, `${part}/section`])
                    .flatMap(sections => Observable.from(sections));
            })
            // Get the chapters
            .flatMap(section => {
                return this.backend
                    .getJSON(`[Next URL]`, [`${section}/chapter1`, `${section}/chapter2`])
                    .flatMap(chapters => Observable.from(chapters));
            })
            // etc.
            .subscribe(console.log)
    }
}

let t = new Demo();
t.getBook('cool');

输出:

cool/part1/section1/chapter1
cool/part1/section1/chapter2
cool/part1/section2/chapter1
cool/part1/section2/chapter2
cool/part2/section1/chapter1
cool/part2/section1/chapter2
cool/part2/section2/chapter1
cool/part2/section2/chapter2