【问题标题】:Angular 2 http.get request performed multiple timeAngular 2 http.get 请求多次执行
【发布时间】:2017-03-21 10:36:31
【问题描述】:

在我的服务中,我有一个从服务器获取一些数据的函数。我的应用程序的几个部分在初始化时调用此函数。我想做的是:如果已经发送了一个请求,则另一个等待它的响应(他们不需要自己提出请求)。

所以我的代码是:

@Injectable()
export class UserService implements OnInit {
  ngOnInit(){
        this.getUserInformations();
  };

  public getUserInformations(forceRefresh?: boolean): Observable<Object>{

        if(this.userInformationsLastObservable == null) {
            console.log('Making a request'); // called only once at init
            this.userInformationsLastObservable = this.http.get(this.baseUrl + "informations")
            .map((result: Response) => {
                console.log('map is called'); // called 5 times at init
                let userInformations = result.json();
                /* So future calls will perform a new request */
                this.userInformationsLastObservable = null;
                return userInformations;
            });
        }

        return this.userInformationsLastObservable;
    };
}

有几个组件这样称呼它:

@Component({
  selector: 'app-leaderboard',
  templateUrl: 'leaderboard.component.html',
  styleUrls:  ['leaderboard.component.css'],
  providers: []

})
export class LeaderboardComponent implements OnInit
{
  ngOnInit(){
      this.userService.getUserInformations().subscribe((userInformations) => {
        this.userInformations = userInformations;
        /* this function does not make any call to the User service */
        this.refresh();
      }, () => {
        this.isLoading = false;
      });

    };
}

问题是:从控制台的网络面板中,我看到在初始化时发送了 5 个请求。并且“调用地图”也打印了 5 次,而“发出请求”只调用了一次。

我做错了什么?

感谢您的帮助

【问题讨论】:

  • 您是否真的在网络选项卡中看到了 5 个网络请求?可以截图吗?
  • 是的 :)(编辑了我的帖子)
  • 好的,我现在很确定这与 Angular 2 服务不是单例的事实有关(参见 stackoverflow.com/a/36200020/6408940)。会做一些测试
  • 其实没有。 “发出请求”仅打印一次这一事实表明它们都使用相同的实例(在应用程序模块级别声明)。
  • this.refresh(); 在做什么?

标签: angular rxjs angular2-http angular2-observables


【解决方案1】:

发现问题出在我对 rxjs Observable 工作原理的误解。我不知道每次您订阅其中一个时,它都会重新执行它。 在这里,每次我订阅this.userInformationsLastObservable 时,它都会再次进行http 调用。我以为只会在创建时进行调用,然后在收到响应时通知所有订阅者。

所以我想我会通过使用主题来解决这个问题。

【讨论】:

  • 你检查我的答案了吗?
  • 是的,但是当函数返回空的 Observable 时,我的订阅者不会收到 HTTP 请求已完成的通知(并且永远不会得到它的响应)。
  • 啊好吧不知道这些细节
  • 我在我的 HttpClient 中使用 ReplaySubject。使用 ReplaySubject,您可以指定已完成订阅的重播次数。
【解决方案2】:

收到另一个请求的响应后发送的请求应该注册在组件中服务的订阅方法中。

在组件中:

constructor(private _service: Service) { }

ngOnInit() {
  this._service.getUserInformations().subscribe(
    res => {
      // call another service;
    }
}

无论响应数组的长度如何,第二个请求都只会发送一次。

【讨论】:

  • 我的应用程序的所有部分都调用同一个请求,而不是“发送请求 1,然后发送请求 2”。它是“发送请求 1,(……某个时间……),发送请求 1”。但如果已经有一个“请求 1”待处理,他们应该等待它而不是再做一个。
  • 同一个请求还是不同请求都无所谓。 this.http.get(this.baseUrl + "informations") 必须返回 5 个元素数组,.map 迭代 5 次,调用体 5 次。检查您的 api 的响应。
  • no 响应只有一个对象,我可以在控制台的网络选项卡中看到 5 个调用。
  • 请把代码 sn -p 粘贴到你调用服务方法的地方
  • 好的,我已经编辑了我的帖子。在服务onInit 和组件的onInit 中有调用
【解决方案3】:
public getConfig(): ReplaySubject<HomeConfig> {

    if (this.replayConfigRequest) {
        return this.replayConfigRequest;
    }

    this.configRequest = this.http.get<HomeConfig>(this.meta.configUrl);

    this.replayConfigRequest = new ReplaySubject<HomeConfig>(1);

    this.configRequest.subscribe(this.replayConfigRequest);

    return this.replayConfigRequest;
}

【讨论】:

    猜你喜欢
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多