简体   繁体   English

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

[英]Angular2/rxjs: Subscribe not firing on Observable expression of mergeMaps & forkJoins

I have a service that has a method that is essentially: 我有一个服务,其方法基本上是:

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

(I've inlined - and slightly simplified - some called methods, which is why it's such a huge expression, and hence the repetition in the getJSON args.) (我已经内联 - 稍微简化 - 一些被称为方法,这就是为什么它是如此巨大的表达式,因此在getJSON args中重复。)

assignAndReturn is just: assignAndReturn只是:

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

.subscribe(...) ing to this doesn't seem to work. .subscribe(...)这似乎不起作用。 It seems to only get partway down the expression tree, not 'making it' all the way to getting the chapters. 它似乎只是在表达树的中途,而不是“制作它”一直到章节。

I really don't know what's happening. 我真的不知道发生了什么。 It's almost as if I need to be subscribing to the 'inner' parts, but then the outer subscription won't fire... 这几乎就像我需要订阅“内部”部分,但外部订阅不会触发......

You could try a pattern like this, leveraging flatMap . 您可以尝试这样的模式,利用flatMap Once the previous event finishes, flatMap will continue with the Observable returned by it's callback. 一旦上一个事件结束, flatMap将继续使用它的回调返回的Observable It helps with readability quite a bit and enables you to spy on your stream along the way. 它有助于提高可读性,使您能够在整个过程中监视您的流。

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

This outputs: 这输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM