2017-05-02 67 views
1

的可观表达我有,有一个方法,它本质上是一种服务:Angular2/rxjs:订阅不开火mergeMaps&forkJoins

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(...)对此似乎不起作用。它似乎只能在表达树中下移,而不是“成为”获得章节的途径。

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

回答

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 
+0

我明白你在说什么,但我真的很喜欢这本书本身从可观察到的(发射而非章,我想成为书籍结构的一部分)。我希望返回observable返回的方法就是这本书,它只是需要在这样做之前递归地'解析'一些字段。 –

+0

特别是,我不希望这本书在它完全形成之前从观察者中发出。我正在订阅来自解析器的'getBook(name)',并且我不想在加载数据之前加载页面。 –

+0

您可以采用上述结构并将'.toArray()'添加到结尾。这将在继续前进之前将所有结果收集到一个数组中。在巫婆之后,您可以使用'.map(...)'来重新组合它,但是您需要。 – Graztok