缓冲角度服务HttpClient请求

时间:2018-08-08 12:34:17

标签: angular rxjs

我正在尝试在角度服务内部实现一个缓冲区,以防止http调用多次连续被调用时多次发出。为此,我使用debounceTime运算符和BehaviourSubject在每个新订阅上立即发出其最后一个值。

@Injectable({
  providedIn: 'root'
})
class MyService {
  private requestBuffer = new BehaviorSubject<any>(null);
  private requestBuffer$ = this.requestBuffer
    .asObservable()
    .pipe(
      debounceTime(1000),
      mergeMap(() => this.http.get('/myurl'))
    );

  constructor(private http: HttpClient) { }

  doRequest() {
    return this.requestBuffer$;
  }
}

@Component({
  selector: 'app-my-component-1'
})
class MyComponent1 implements OnInit {
  constructor(private myService: MyService) { }
  
  ngOnInit() {
    this.myService.doRequest()
      .subscribe()
  }
}

@Component({
  selector: 'app-my-component-2'
})
class MyComponent2 implements OnInit {
  constructor(private myService: MyService) { }
  
  ngOnInit() {
    this.myService.doRequest()
      .subscribe()
  }
}

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [
    MyComponent1,
    MyComponent2
  ],
  providers: [
    MyService,
  ]
})
class MyModule {

  constructor() { }
}
<app-my-component-1 />
<app-my-component-2 />

以上代码无法正常工作,我不太了解自己在做什么错。 当这两个组件都到达其OnInit生命周期挂钩时,我期望HttpClient的get方法将被反跳并且仅被调用一次。但是,事实并非如此,正在触发两个get调用。

我希望解释很清楚。

要达到获得缓冲的http调用的最终目的,我做错了/误解是什么?

谢谢!

1 个答案:

答案 0 :(得分:4)

您必须添加share()运算符,才能在多个订阅之间共享可观察对象:

private requestBuffer$ = this.requestBuffer
 .asObservable()
 .pipe(
   debounceTime(1000),
   mergeMap(() => this.http.get('/myurl')),
   share()
);

如果您使用shareReplay(),则不需要使用BehaviourSubject,但是最后,这并不重要。

要“抛弃” BehaviourSubject,我怀疑这应该足够了:

class MyService {
  private requestBuffer$ = this.http.get('/myurl').pipe(
    debounceTime(1000),
    shareReplay()
  );

  constructor(private http: HttpClient) { }

  doRequest() {
    return this.requestBuffer$;
  }
}

尽管恐怕您打了两个电话,并且它们相距2秒以上,但第二个电话不会触发,但是您应该自己进行测试

相关问题