【问题标题】:Merging two observerable合并两个可观察的
【发布时间】:2018-07-16 10:37:20
【问题描述】:

使用的技术 - Angular 4,rxjs 试图实现 - 从两个不同的服务器获取数据(json响应),通过将列表与可观察数组绑定来合并数据并显示在列表中。

**Search component TS** 

    @Component({
      selector: 'word-search',
      templateUrl: 'wordSearch.component.html',
     })
    export class WordSearchComponent {
      term = new FormControl();
      items: Observable<Array<string>>;

      constructor(private wikipediaService: WikipediaService) { }
      ngOnInit() {
        this.items = this.term.valueChanges
          .debounceTime(1000)
          .distinctUntilChanged()
          .switchMap(term => this.wikipediaService.search(term));

        }  
    }

*****Search component chtml***** 

    <div>
        <h2>Search</h2>
        <input type="text" [formControl]="term"/>
        <ul>
      <li *ngFor="let item of items|async ">{{item}}</li>

        </ul>
      </div>

服务代码 - 问题就在这里

getWikipediaObserver(term:string):Observable<any>
  {
    var wikipediaUrl = 'http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK';

      var search = new URLSearchParams()
      search.set('action', 'opensearch');
      search.set('search', term);
      search.set('format', 'json');

      return this.jsonp
        .get(wikipediaUrl, { search })
        .map((request) => request.json()[1]).catch(this.handleError);


  }
  getItuneObserver(term: string)
  {
    var secondUrl = 'https://itunes.apple.com/search?callback=JSONP_CALLBACK&limit=20';
    var search = new URLSearchParams()
    search.set('term', term);
    search.set('format', 'json');


    var ituneObserver = this.jsonp
      .request(secondUrl, { search })
      .map((request) => request.json().results.map(item => {
        return item.trackName + " " +item.collectionCensoredName+" " +item.artistName;
      })).catch(this.handleError); 

      return ituneObserver;
  }

  search(term: string): Observable<any> {
   var observer1= this.getItuneObserver(term);
   var observer2= this.getWikipediaObserver(term);
   return merge(observer1,observer2); ***//PROBLEM***

  }

merge 运算符发出两次值,一次用于第一个观察者,然后用于 第二个观察者。列表将首先显示第一组并用新项目覆盖旧项目。我希望合并只发出一次所有数据。有什么想法吗?

【问题讨论】:

    标签: javascript angular rxjs observable


    【解决方案1】:

    你可以使用 rxjs 库的 forkJoin 方法加入多个 observable

     // import { forkJoin } from 'rxjs/observable/forkJoin';
    
     forkJoin(
      this.this.getItuneObserver(term),
      this.getWikipediaObserver(term)
    )
    .subscribe(([res1, res2]) => {
      this.propOne = res1;
      this.propTwo = res2;
    });
    

    【讨论】:

    • 让结果:字符串[] = []; combine.subscribe(latestValues => { const [ response1 , response2 ] = latestValues; result=result.concat(response1); result=result.concat(response2); });返回(结果);我在结果对象中得到结果,但是“返回(结果)”首先发生,然后 forkJoin 操作完成。如何确保首先连接结果,然后只有它应该从函数返回。
    【解决方案2】:

    感谢普拉莫德·帕蒂尔。我是怎么解决的

      search(term: string) {
    
        const combined =forkJoin(
         this.getItuneObserver(term),
        this.getWikipediaObserver(term)
      );
    
      return combined;
    
    
      }
    

    在component.ts中订阅

        import { of } from 'rxjs/observable/of';
       export class WordSearchComponent {
              term = new FormControl();
    
             items: Observable<Array<string>>;
              result: string[] = [];
              ngOnInit() {
    
                var combined=this.term.valueChanges
                  .debounceTime(1000)
                  .distinctUntilChanged()
                  .switchMap(term => this.wikipediaService.search(term));
    
                  combined.subscribe(latestValues => {
                   const [ response1 , response2 ] = latestValues;
                   this.result=this.result.concat(response1);
                   this.result=this.result.concat(response2);
                   this.items = of(this.result);
               });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 2023-03-31
      • 2020-09-22
      • 1970-01-01
      • 2020-04-03
      • 2019-10-18
      相关资源
      最近更新 更多