rxjs Observable - 订阅结果循环并在条件中断/无法读取属性' subscribe'未定义的

时间:2018-04-19 17:11:18

标签: javascript typescript rxjs observable

我是rxjs的新手,似乎找不到我想要做的正确的算子。

在我的例子中,我有一个数组,我需要用另一个observable的结果填充,一旦我在该数组中有足够的结果进行订阅调用,我想打破并返回数组。

// for reference, there is a class variable called keys

    result = getResults(data, index).subscribe((result: any[]) => { 
          doSomethingWith(result);
    });

    getResults(data: any[], index: number) : Observable<any[]> {
       obsFunctionThatGetsMeData(keys[index]).subscribe(result => 

         data = data.concat(result);

          if(data.length >= NEEDED_NUM_DATA) {
              return Observable.of(data);

          } else {

            /* need to call obsFunctionThatGetsMeData(keys[index++]) and do the same logic as above. */

          }
       );
    }

我知道在订阅中订阅是不好的做法,这只是我正在寻找的想法。我知道takeWhile工作的条件,但我不知道如果条件失败我怎么可以拨打额外的电话。有谁知道哪种算子最适合这种行为?

谢谢!

  • obsFunctionThatGetsMeData返回Observable

解决了我自己的问题 使用递归&amp; switchmap

getResults(data: any[], index: number): Observable<any> {
   return obsFunctionThatGetsMeData(keys[index]).pipe(
        switchMap(result => {
            if (result) {
                data= data.concat(result);

                if (data.length < NEEDED_NUM_DATA && index < keys.length) {
                    return getResults(data, ++index);
                } else {
                    return Observable.of(data);
                }
            }
        }));
}

3 个答案:

答案 0 :(得分:0)

我不是RxJS的专家,但我认为这样的事情应该是可能的:

Rx.Observable.from(obsFunctionThatGetsMeData)
  .take(NEEDED_NUM_DATA)
  .subscribe(doSomethingWith);
  

public take(count:number):Observable仅发出第一个计数   源Observable发出的值。

这只是一个思考并且不会假装成一个有效解决方案的想法。

答案 1 :(得分:0)

看起来像obsFunctionThatGetsMeData会发出一次(就像HTTP请求一样),并且您希望将这些请求的NEEDED_NUM_DATA数量的结果收集到数组中。 它还应该附加到数据参数中已有的任何内容吗?

试试这个:

getResults( data: any[], index: number ): Observable<any[]>
{
    return Observable.range( index, NEEDED_NUM_DATA )
        .concatMap( i => obsFunctionThatGetsMeData( keys[i] ) )
        .reduce(( acc: any[], value ) => acc.concat( value ), data );
}

答案 2 :(得分:0)

承诺是你的朋友。 (因为你正在处理单个值)。

虽然您认为自己正在处理结果流(可观察对象),但实际上您实际上只是使用单个值。每个值都在一个循环中独立操作,该循环将结果推送到数组中。因此import { Injectable } from '@angular/core'; //default from CLI command // import { FsService } from 'ngx-fs'; // add this line After step 1 // @Injectable() export class youServiceNameService { myDatabaseTable1: Array< any >; // you can pull all the DB in the var myDatabaseTable2: Array< any >; // I separated the tables fileSystem: any; // where I put my FS constructor( private _fsService: FsService ) { this.fileSystem = this._fsService.fs; // the property fs of // the _FsService contents is described here https://nodejs.org/api/fs.html this.readDB(); } readDB() { this.fileSystem.readFile( 'databaseOrTable.json', ( error, data ) => { if ( error ) throw error; this.clients = JSON.parse( data ); console.log( this.clients ); } ); } } 个独立变量合并为一个集合。

此代码更容易合理化并实现您的目标:

NEEDED_NUM_DATA