rxjs Observable - 订阅导致循环并在条件下中断/无法读取未定义的属性“订阅" [英] rxjs Observable - subscribe to result in loop and break on condition / cannot read property 'subscribe' of undefined

查看:104
本文介绍了rxjs Observable - 订阅导致循环并在条件下中断/无法读取未定义的属性“订阅"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 rxjs 的新手,似乎无法找到适合我要做的事情的正确运算符.

I am new to rxjs and can't seem to find the correct operator for what I am trying to do.

在我的示例中,我有一个数组,我需要用另一个 observable 的结果填充,一旦我在该数组中通过 subscribe 调用获得足够的结果,我想中断并返回该数组.

In my example, I have an array I need to populate with results from an another observable, and once I have enough results in that array from making subscribe calls, I want to break and return the array.

// 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 在某个条件下工作,但我不知道如果该条件失败,我该如何进行额外的调用.有谁知道哪种运算符最适合这种行为?

I know it is bad practice to put a subscribe in a subscribe, this is just the idea of what I'm looking for. I know takeWhile works on a condition, but I don't see how I can make extra calls if that condition fails. Does anyone know what operator is best for this kind of behavior?

谢谢!

  • obsFunctionThatGetsMeData 返回 Observable

解决了我自己的问题使用递归 &切换图

Solved my own question Using recursion & 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);
                }
            }
        }));
}

推荐答案

Promises 是你的朋友.(因为您使用的是单个值).

Promises are your friend here. (because you are working with single values).

尽管您认为您正在处理一系列结果(可观察量),但实际上您一次只处理一个值.每个值都在循环中独立操作,将结果推送到数组中.所以 NEEDED_NUM_DATA 个独立变量合并成一个集合.

Although you think you are working with a stream of results (the observables), you are actually just working with a single value at a time. Each value is independently operated on in a loop that pushes the result into an array. So NEEDED_NUM_DATA independent variables consolidated into a a collection.

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

This code is much easier to rationalize about and to realize your goal:

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));

这篇关于rxjs Observable - 订阅导致循环并在条件下中断/无法读取未定义的属性“订阅"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆