嵌套可观察项/在可观察项内订阅

时间:2019-07-23 11:33:46

标签: rxjs

读到永远不要subscribe在另一个可观察物之内,我在理解如何正确处理嵌套可观察物时遇到了很大的困难。

对于每个发出的Candidate,我想与多个正则表达式匹配,以可观察的getPatterns$()形式提供。如果找到一个,它将被附加到Candidate对象上。

 class Candidate {
    public name: string;
    public matchingRegularExpression: RegExp;
 }

 listOfCandidates = [new Candidate('one'), new Candidate('two')];

 private matchCandidates$(textToMatch: string): Observable<Candidate> {
    return from(this.listOfCandidates)
      .pipe(
        map(f => { 
          f.regExp = this.getRegExp(f); // sequential
          return f;
        }),
        map(cand: Candidate => {
           this.getPatterns$().subscribe(patterns => {
             if (....do some regexp matching...){
                cand.matchingRegularExpression = pattern;
             }
           });
        })
      )

我尝试使用mergeMapswitchMap,但是当您要将1个外部对象与n个内部对象合并时,似乎使用了这些对象。但是在此示例中,我的内部可观察对象应该简单地扩展我的Candidate对象并发出2个值。

1 个答案:

答案 0 :(得分:1)

首先,这被认为是一种不好的做法,因为您完全失去了第二个订阅的引用,如果源继续发出,则可能导致泄漏。

幸运的是,我们有一个名为switchMap的运算符,它使我们可以打开一个新的Observable,从而避免在观察器函数中进行订阅。

  

switchMap与其他展平运算符之间的主要区别是取消效果。在每次发射时,先前的内部可观测值(您提供的函数的结果)都会被取消,并订阅新的可观测值。您可以通过切换到新的可观察词来记住这一点。

编辑:添加代码段

class Candidate {
    public name: string;
    public matchingRegularExpression: RegExp;
 }

 listOfCandidates = [new Candidate('one'), new Candidate('two')];

private matchCandidates$(textToMatch: string): Observable<Candidate> {
    return from(this.listOfCandidates)
      .pipe(
        map(f => { 
          f.regExp = this.getRegExp(f); // sequential
          return f;
        }),
        switchMap(cand: Candidate => {
          return this.getPatterns$().pipe(
            map(patterns => {
              if (....do some regexp matching...){
                cand.matchingRegularExpression = pattern;
              }
              return cand
            })
          )})
         )