【问题标题】:How to use $q.all and $q.defer in Angular 5?如何在 Angular 5 中使用 $q.all 和 $q.defer?
【发布时间】:2019-01-09 15:12:27
【问题描述】:

我正在尝试将现有的 AngularJs 代码迁移到 Angular 5。我目前在 forEach 函数中运行许多 API 调用。以前我曾经在每个函数中运行 $q.defer ,并在成功或错误函数调用中运行 .resolve() 。在那之后$q.all。现在我不确定如何将它与 observables 一起使用。

这就是我的组件的外观。

testArray = [1,2,3,4,5,.6];
  resultArray = [];

  constructor(private timeoutService: TimeoutService) {
    this.testFn();
  }


 testFn(){
  this.testArray.forEach((n) => {
    this.timeoutService.getItemsCallback(n, this.successFn.bind(this), this.errorFn.bind(this))
  })
 }

 successFn(r){
   this.resultArray.push(r);
   console.log(r)
 }

 errorFn(e){
   this.resultArray.push(e);
   console.log(e);
 }

这是我的服务文件。

public GetItems(request: any): Observable<any> {
    console.log(request)
    return this.http.get(`https://jsonplaceholder.typicode.com/posts/${request}`);
  }


  getItemsCallback(request, successFn, errorFn) {
    this.GetItems(request).
      subscribe(
        response => {
          successFn(response);
        },
        error => { 
          errorFn();
        }
      );
  } 

我想在所有 API 调用完成后做点什么。我看到有一个名为 forkJoin 的函数,但我不知道如何使用它。 这是一个stackblitz链接。 https://stackblitz.com/edit/angular-suetah?file=src%2Fapp%2Ftimeout.service.ts

【问题讨论】:

  • forkJoinzip 用于$q.all

标签: angular rxjs observable


【解决方案1】:

这有多种使用 RxJS 的解决方案。

此答案是对 Picci 答案的补充。

Picci 使用 MergeMap。 MergeMap 的问题在于您获得的响应顺序有时可能与请求的顺序不同。

ForkJoin,将保留顺序并在收到所有响应后返回。

ConcatMap 会保留顺序,但会在每个请求完成后返回。

如果您不关心在所有请求完成之前等待的时间,我想您可以使用 ForkJoin。

会是这样的:

 testArray = [1,2,3,4,5,6];
 obsArray = []
 this.testArray.forEach((n) => {
    this.obsArray.push(this.timeoutService.getItemsCallback(n))
 })

 forkJoin(this.obsArray).subscribe((res) => {
   //Write code for success callback
 },
 (err) => {
   //Write code for error callback
 },
 () => {
   //Write code to do something when all requests are complete
 })

但是,如果你想使用 mergeMap 或 concatMap(阅读我上面的解释并决定),你可以做 Picci 所做的。

如果您决定使用 concatMap,只需在他的代码中将 mergeMap 更改为 concatMap。

【讨论】:

    【解决方案2】:

    如果你有几个 http 调用要执行,参数存储在一个数组中,然后你必须在所有这些调用都返回时做一些特定的事情,你可以考虑按照这些思路的方法。

    首先,您使用 RxJs 6.x 的 from 函数从参数数组创建一个 Observable。

    然后您使用mergeMap(又名flatMap)将参数数组转换为代表http调用的Observables数组。

    最后你订阅激活 Observable 链并执行调用,指定当 Observable 链完成时要运行的函数,即当所有 http 调用都返回时。

    代码可能如下所示

    const testArray = [1,2,3,4,5,6];
    from(testArray)
    .pipe(
      mergeMap(param => this.GetItems(param))
    )
    .subscribe(
      result => {// do something with the result},
      error => {// do something if an error occurs},
      () => {// this is the function run when all of the httpCalls have returned}
    )
    

    【讨论】:

      猜你喜欢
      • 2014-04-05
      • 2017-11-23
      • 2023-03-11
      • 2020-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-03
      相关资源
      最近更新 更多