简体   繁体   English

来自Angular中的嵌套订阅的错误

[英]Bug from nested subscriptions in Angular

I am trying nest subscriptions within "subscribe" as some data depends on the response of the previous subscription. 我正在尝试在“订阅”中嵌套订阅,因为一些数据取决于先前订阅的响应。 (Data flows down the subscription chain till it is stored in an array) (数据沿订阅链向下流动,直到将其存储在数组中为止)

I have an array of IDs, I call a service to convert those IDs to Objects. 我有一个ID数组,我调用了一个将这些ID转换为Objects的服务。 Code looks like this: 代码如下:

idArray.forEach(id =>
     this.getObjByID(id)));
}

getOjByID(ID: number): void {
  this._APIService.getObjByID(ID).subscribe(
    obj => {
        this.getDefaultConfig(obj);
    });
}

These Objects are then passed to get a config file for the Obj. 然后将这些对象传递以获得Obj的配置文件。 Code looks like this: 代码如下:

  getDefaultConfig(obj: any): void {
      this._APIService.getDefaultConfig(obj.id).subscribe(
          res => {
              obj.config = res;
              this.getPrices(obj);
          });
  }

Lastly, this object is passed its config to a final subscription, where a price object is appended to the object, and the object is then pushed to an array of objects (and is then rendered on the screen.) Code looks like this: 最后,将此对象的配置传递给最终订阅,在该订阅中将价格对象附加到该对象,然后将该对象推送到对象数组(然后呈现在屏幕上。)代码如下所示:

  getPrices(obj: any): void {
      this._PriceService.getPrice(obj).subscribe(
          res => {
              obj.price = res;
              this.objs.push(obj);
          });
  }

I don't understand subscribe/observables enough to understand the cause of this bug that I am experiencing. 我对订阅/可观察对象的理解不足以了解我遇到此错误的原因。 Essentially, I am using subscribe to extract the value of the response. 本质上,我使用订阅来提取响应的值。 The expected behavior is for this chain to be run as many times as the number of ids I have in my idArray, however, it appears that some subscriptions (or functions) are being run again. 预期的行为是此链将运行与idArray中的ID数量一样多的次数,但是,似乎某些订阅(或函数)正在再次运行。 I have no errors in the console, my only indicator is the number of items int he final array "objs". 我在控制台中没有错误,我唯一的指标是最终数组“ objs”中的项目数。

I have tried adding ".first()" or ".take(1)" before ".subscribe" on all my functions and this appears to have fixed duplicate obj objects in my objs array, however they all had the same "price" object. 我尝试在所有函数的“ .subscribe”之前添加“ .first()”或“ .take(1)”,这似乎在我的objs数组中具有固定的重复obj对象,但是它们都具有相同的“ price”宾语。

What am I doing wrong with observables that is causing this to happen? 导致这种情况发生的可观察物在做什么?

Your issue could be caused by a strangely-expected behavior of subscribing to the same Observable more than once. 您的问题可能是由于多次订阅同一Observable行为异常而引起的。 I ran into this issue when i was caching API responses through my service. 我在通过服务缓存API响应时遇到了这个问题。

The idea is that when you subscribe to an observable a second time, the value is retrieved again (It's a "hot" observable), so the first subscription also receives the new (or same) value, thus your next layer of functions are being called twice (or more depending on how many subscribers there are). 这个想法是,当您第二次预订可观察对象时,将再次检索该值(这是“热”可观察对象),因此第一个预订也将接收新的(或相同的)值,因此下一层功能被呼叫两次(或更多次,取决于有多少用户)。

You can easily fix this by adding .share() to the end of your observable wherever it's being created. 您可以通过在可观察对象的创建位置的末尾添加.share()来轻松解决此问题。 For example, here's a snippet of a code in my current project: 例如,这是我当前项目中的一段代码:

const resp = this.http.get(url)
  .map( /* Some stuff is done and a value is returned */ )
  .catch(this.handleError)
  .share();

return resp;

A good explanation that really helped it click for me is here: https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html 一个真正帮助它点击的很好的解释是在这里: https : //blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html

You've mentioned that this change caused your end objects to be null. 您已经提到此更改导致最终对象为空。 I'm not sure if that's caused by some issue in the code. 我不确定这是否是由于代码中的某些问题引起的。 I'll keep this solution posted because it is what worked for me in your case. 我会继续发布该解决方案,因为这对您来说很有效。

(I was doing the same thing - exactly three levels of subscriptions - but the results were fine after adding .share in my case.) (我正在做同样的事情-恰好是三个级别的订阅-但在我的情况下添加.share后结果还不错。)

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

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