Angular 如何在加载其余数据的同时以角度预加载部分数据?

Angular 如何在加载其余数据的同时以角度预加载部分数据?,angular,httpclient,Angular,Httpclient,当我试图加载第一页数据并在后台加载整个数据集时显示它时,我认为我很聪明。我使用了以下代码 ngOnInit() { this.service.getStuff(0, 10) .subscribe(suc => this.subset = suc); this.service.getStuff() .subscribe(suc => this.data = suc); } 然后,我在API中设置断点,获取并释放第一个调用,保留第二个未释放的调用。但是,根据我

当我试图加载第一页数据并在后台加载整个数据集时显示它时,我认为我很聪明。我使用了以下代码

ngOnInit() {
  this.service.getStuff(0, 10)
    .subscribe(suc => this.subset = suc);

  this.service.getStuff()
    .subscribe(suc => this.data = suc);
}
然后,我在API中设置断点,获取并释放第一个调用,保留第二个未释放的调用。但是,根据我的浏览器中的“网络”选项卡,两个呼叫都将挂起,直到两个呼叫都完成

我离预加载工作的地方很近还是很远


实际调用由通常的HttpClient和GET执行,返回一个可观察的对象。

为此,最好使用一些RxJS操作符

这会让双方都开火。先到先得

merge(this.service.getStuff(0, 10), this.service.getStuff()).subscribe(data => {
  // do stuff with data
});

下面,switchMap将使allStuff$仅在initialStuff$发出后激发。 这将仅在第一个GET发出后触发第二个GET

const intialStuff$ = this.service.getStuff(0, 10).pipe(
  share()
);

const allStuff$ = intialStuff$.pipe(
  switchMap(() => this.service.getStuff())
);

intialStuff$.subscribe(...);
allStuff$.subscribe(...)


请注意,由于没有任何请求会阻止渲染,因此您肯定应该使用第一种方法。它将更快地获取所有数据。

角度HttpClients
get()
每次都应该返回一个新的可观察对象,并且不会表现出您描述的行为

这完全取决于
This.service.getStuff()
的实现。如果实现如下所示,它应该在每个调用中返回一个新的
可观察的
,并使其独立于任何其他调用/订阅

doStuff() {
    return this.http.get('someUrl');
}
-我延迟了时间来帮助演示。运行此操作时,第一次调用将完成,并将在第二次调用之前呈现

具有初始化逻辑的组件:

ngOnInit(){
this.myService.doSomething('todos/1', 100)
  .subscribe(resp => {
    this.first = resp;
  });

this.myService.doSomething('comments', 1500)
  .subscribe(resp => {
    this.second = resp;
  })
}
示例服务:

@Injectable()
export class MyService {
  constructor(private http: HttpClient){}

  doSomething(route: string, withDelay?: number) {
    return this.http.get('https://jsonplaceholder.typicode.com/' + route)
      .pipe(delay(withDelay));
 }
}

是的,这正是我所期望的。我没有在服务的方法中使用延迟来测试它,只是在我调用的控制器中使用了一个断点。但这不应该有任何区别——一旦第一次调用从WebAPI发出,就应该在客户端屏幕上呈现。不知道如何设置StackBlitz(包括实际的后端调用)…我看我不清楚。当我运行您的Blitzy时,我可以在网络选项卡中看到两个响应同时到达(至少看起来是这样)。然后,需要一定的延迟才能在屏幕上呈现第二个。但是,我的iaim并没有推迟移交。它正在调用第一个调用的格式副本,而第二个调用正在进行。您知道一种方法可以使您在示例中调用的后端在某些调用中变得非常慢吗?我将再试一次。就我所见,第二个较大的调用(我在后端通过简单地在那里放置一个断点并让它挂起而停止)在网络选项卡中被列为挂起(它应该挂起)。出乎意料的是,第一个从断点释放并应该返回的调用也被列为挂起。这太奇怪了。我仍然会得到相同的意外行为,但如果在timer(4000.subscribe)(\u=>this.service.getStuff()…)之后执行第二个调用,则会得到预期的结果。这就好比如果两个调用中有一个未设置为计时器。。。老实说,我不太明白。除非您使用switchMap/concatMap/mergeMap等展平操作符,否则RxJS将绑定它们。这些操作员说,在一个可观测源发射后,然后订阅另一个。实际上触发HTTP请求的是订阅行为。订阅创建了一个新的数据生产者,这种观察质量被称为“热观察”,适用于所有HTTP请求。关于您的陈述“订阅的行为实际上触发了HTTP请求”,我完全同意。然而,令我惊讶的是,基于此,我的问题样本应该彼此独立地发射两次。然而,情况并非如此。或者,在第二次调用完成之前,调用的状态被标记为挂起,并且不会为第一次调用提供信息。我怀疑这与我在开发模式下运行localhost上的所有内容有关。将其设置为一个单独的项目会很好,但我不知道如何设置(.NET back/Angular front)。为此,我使用了基于merge的第一个示例。一切正常。但是,我尝试在不同的情况下应用基于switchMap和share的第二个示例(从路由中获取ID,然后将其作为参数加载数据)。遗憾的是,它没有按照我希望的方式工作,所以我想知道你是否有时间来看看我是如何误解你的观点的。你所描述的不是预期的行为。根据答案和评论,我推测还有其他事情发生。@bryan60。我注意到,作为timer(1000).subscribe(…)的结果调用第二个调用会产生预期的行为,因此计算机不知何故将这两个调用阻塞在一起。你确认了我最初的期望(我放弃了,因为我最终对自己的技能失去了信心)。我很想建立一个可复制的示例,但我不确定如何创建,因为这是一个结合了.NET和Angular的问题……我多年来一直在研究Angular和.NET后端,从未遇到过这样的问题。这可能与您在API中设置喙点的方式有关,或者如果您有某种可能难以控制的拦截器,或者您的服务中发生了阻碍http客户端的事情。