繁体   English   中英

rxjs可观察-订阅导致循环并在条件上中断/无法读取未定义的属性'subscribe'

[英]rxjs Observable - subscribe to result in loop and break on condition / cannot read property 'subscribe' of undefined

我是rxjs的新手,似乎无法为我想做的事情找到正确的运算符。

在我的示例中,我有一个数组,需要使用另一个可观察的结果填充该数组,一旦在该数组中进行订阅调用得到足够的结果,我想中断并返回该数组。

// 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

使用递归和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);
                }
            }
        }));
}

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

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

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

这只是思考的主意,并不假装是可行的解决方案。

看起来obsFunctionThatGetsMeData发出一次(就像HTTP请求一样),并且您希望将NEEDED_NUM_DATA个请求的结果收集到数组中。 而且还应该附加到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 );
}

答应是您的朋友。 (因为您正在使用单个值)。

尽管您认为自己正在处理一系列结果(可观察的结果),但实际上您一次只使用一个值。 每个值都在循环中独立操作,该循环将结果压入数组。 因此,将NEEDED_NUM_DATA自变量合并到一个集合中。

这段代码更容易合理化和实现您的目标:

 var NEEDED_NUM_DATA = 4; var collection = []; async function getResults() { let url = 'https://jsonplaceholder.typicode.com/posts/'; let i = 1; while(collection.length <= NEEDED_NUM_DATA) { let result = await getsMeData(url + i++); collection.push(result); } } async function getsMeData(url) { const response = await fetch(url); const json = await response.json(); return json; } getResults() .then(()=>console.log(collection)); 

暂无
暂无

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

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