Angular - Correctly using RXJS expand operator to make recursive http calls

柔情痞子 提交于 2019-12-19 04:24:20

问题


I am attempting to make recursive http calls to Reddit's API using a value from the previous call. The problem is that the previous call is not finished before the next one starts, so duplicate calls are being made. The "after" value should be updated for every call until the "after" value is undefined. I found this related post and have attempted to use the solution described, but I can't figure out how to make sure the previous call is finished before making the next call. Below is my actual code:

private getSavedPostsForAuthenticatedUser(username: string, after: string, userPosts: any) {
    const headers = new Headers();
    if (!userPosts) {
        userPosts = [];
    }
    headers.append('Authorization', `Bearer ${this._token}`);
    const redditUrl = `${RetainerConfig.redditOauthUrl}user/${username}/saved`;
    const url = after ? `${redditUrl}/?after=${after}` : redditUrl;
    return this._http.get(url, { headers: headers })
        .map(response => response.json())
        .expand(response => {
            if (response.data) {
                for (const post of response.data.children) {
                    userPosts.push(post);
                }
                if (response.data.after) {
                    return this.getSavedPostsForAuthenticatedUser(username, response.data.after, userPosts);
                }
            }
            return Observable.of(userPosts);
        });

回答1:


Returning the same function getSavedPostsForAuthenticatedUser will cause recursive expands. To solve this you need to separate the http observable.

  private getSavedPostsForAuthenticatedUser(username: string, after: string, userPosts: any) {
    const request$ = this._getRequest(username, after, userPosts);
    if (!userPosts) {
      userPosts = [];
    }
    return request$
      .expand(response => {
        if (response.data) {
          for (const post of response.data.children) {
            userPosts.push(post);
          }
          if (response.data.after) {
            return this._getRequest(username, response.data.after, userPosts);
          }
        }
        return Observable.of(userPosts);
      });
  }

  private _getRequest(username: string, after: string) {
    const headers = new Headers();
    headers.append('Authorization', `Bearer ${this._token}`);
    const redditUrl = `${RetainerConfig.redditOauthUrl}user/${username}/saved`;
    const url = after ? `${redditUrl}/?after=${after}` : redditUrl;

    return this._http.get(url, {headers: headers})
      .map(response => response.json());
  }

To stop the expanding you may use Observable.empty(). Please refer to this post.



来源:https://stackoverflow.com/questions/44981974/angular-correctly-using-rxjs-expand-operator-to-make-recursive-http-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!