Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多个rxjs http请求6_Rxjs_Angular6 - Fatal编程技术网

多个rxjs http请求6

多个rxjs http请求6,rxjs,angular6,Rxjs,Angular6,我有以下代码: private getUsers(page, result) { result = result||[]; return this.http.get(API_URL + '/users?page=1') .pipe(map(response => { const response_filter = response.json(); const users = response_filter['data']; const pages = response_filt

我有以下代码:

private getUsers(page, result) {
result = result||[];
return this.http.get(API_URL + '/users?page=1')
.pipe(map(response => {
  const response_filter = response.json();
  const users = response_filter['data'];
  const pages = response_filter['total_pages'];
  Array.prototype.push.apply(result, users.map((user) => new User(user)));
  while (page != pages)
  {
    this.http.get(API_URL + '/users?page=' + page)
    .pipe(map(resp => {
      console.log('test');
      const response_filter = resp.json();
      const users = response_filter['data'];
      Array.prototype.push.apply(result, users.map((user) => new User(user)));
      return result;
    }))
    .pipe(catchError(val => of(`Caught inner error: ${val}`)));
    page += 1;
  }
  return result;
}))
.pipe(catchError(val => of(`Caught error: ${val}`)));
}
代码在console.log'test'之前运行良好。此日志不会显示,但循环可以正常迭代。
以前我尝试过相同的函数,但是是递归的。也有同样的问题。

实现这一点的最佳方法是使用flatMap和forkJoin操作符创建一个表示您要发出的所有请求的可观察对象。代码中的异步操作存在许多问题,这意味着返回的结果将不包括内部HTTP请求的结果

我提议如下:

private getUsers(page, result) {
    return this.http.get(API_URL + '/users?page=1')
    .pipe(
        flatMap((response) => {
            const response_filter = response.json();
            const users = response_filter['data'];
            const pages = response_filter['total_pages'];
            let firstPageUsers: User[] = users.map((user) => new User(user));
            let getAllUsers: Observable<User[]>[];
            getAllUsers.push(of(firstPageUsers));
            while (page < pages)
            {
                getAllUsers.push(this.http.get(API_URL + '/users?page=' + page)
                   .pipe(
                       map(resp => {
                           console.log('test');
                           const response_filter = resp.json();
                           const users = response_filter['data'];
                           return users.map((user) => new User(user));
                       }),
                       // You need to decide if this is how you want errors
                       // handled, it doesn't seem too sensible to me:
                       catchError((err) => {
                           console.log(`Caught inner error: ${err}`);
                           return of([]); // needs to return type Observable<User[]>
                       })
                   )
                );
                page += 1;
            }
            return forkJoin(getAllUsers);
        }),
        map((allResponses) => {
            // allResponses will be an array of User arrays from 
            // all of the observables within the forkJoin, so now
            // we can iterate over all of those to create a single 
            // array containing all of the results.
            result = result||[];
            allResponses.forEach((responseUsers) => {
                 Array.prototype.push.apply(result, responseUsers);
            });
            return result;
        }),
        catchError((err) => {
            console.log(`Caught outer error: ${err}`);
            of(null); // Or whatever - again, think about your error cases.
        })
     );
  }

现在,无论您在哪里调用getUsers,当您订阅此observable时,它应该也会解决所有内部查询。

标记回答很好,但我已经解决了我的问题,可能不是以好的方式,而是使用subscribe使用Martin comment解决了它。首先我订阅了一个get pages count请求,然后我订阅了一个while循环中的get users请求

我在angular是新手,所以也许有人会回答一个问题,我必须在这里使用unsubscribe吗

this._dataSub0 = this.userDataService.getPages().subscribe((pages) => {
  var page_num = pages;
  var i = 1;
  while (i < page_num) {
    this._dataSub = this.userDataService
      .getAllUsers()
      .subscribe(
        (users) => {
            for (let us of users) {
              this.users.push(us);
            }
        }
      );
    i++;
  }
});

public getAllUsers(page): Observable<User[]> {
return this.getUsers(page);
}
private getUsers(page) {
  var result = result||[];
  return this.http.get(API_URL + '/users?page=' + page)
  .pipe(map(response => {
    const response_filter = response.json();
    const users = response_filter['data'];
    const pages = response_filter['total_pages']
    if(pages == page)
      return null;
    Array.prototype.push.apply(result, users.map((user) => new User(user)));
    return result;
  }))
  .pipe(catchError(val => of(`Caught error: ${val}`)));
}
public getPages(): Observable<number> {
  var result;
  return this.http.get(API_URL + '/users?page=0')
  .pipe(map(response => {
    const response_filter = response.json();
    const pages = response_filter['total_pages']
    return pages;
  }))
  .pipe(catchError(val => of(`Caught error: ${val}`)));
}

您需要使用订阅来订阅可观察对象。例如,订阅对于短命的可观察对象,从http请求派生的可观察对象是短命的,一旦http请求完成,它们就会自行终止。对于长寿命的可观察对象,例如那些可以发出多个项目的对象,例如,一个服务通知您必须取消订阅某种变化的内容,或者提供一些其他方法在组件被销毁时终止可观察操作符,如takeWhile、takeUntil等。