首页 > 解决方案 > 处理一个带来下一个请求的 httpclient 直到完成

问题描述

当使用 Sharepoint API 调用超过 100 行的巨大列表或您放入 $top=100 的列表时。你得到列表的字段和一个 __next 变量。这个 __next 变量包含一个指向下一页地址的字符串,您需要查询列表的后续元素。

我的问题在于我无法同步执行 http.get 请求,因此无法知道下一个是否结束。

我尝试了递归方法,构建了我自己的自定义 RxJS 运算符并构建了一个调用subscriber.next 的 Observable,但我总是被后续请求绊倒。

getExpedienteFromUrl(httpUrl?: string): Observable<ExpedienteListAndNextQuery> {
    const urlAddress = (httpUrl ? httpUrl : this.urlSharepointAPIExpedientes );
    return this.http.get<D>(urlAddress, {
      headers: {
        accept: 'application/json;odata=verbose'
      }
    }).pipe(
      map(x => this.mapExpedientesOfObserver(x) ),
      this.getExpedientesPipe()
    );
}

getExpedientesPipe(): Observable <IExpediente[]> {
    return ($source: Observable<ExpedienteListAndNextQuery>) => {
      return new Observable<IExpediente[]>(subscriber => {
        $source.subscribe(
          data => {
            const expedientes: IExpediente[] = data.Expedientes;
            const next: string = data.Next;
            subscriber.next(expedientes);
            if (next) {
              // call to this.getExpedienteFromUrl(next) [Async]
              // so if this where in a do while the following next will always 
              // be undefined
            }
          },
          err => subscriber.error(err),
          () => subscriber.complete()
        );
      });
    };
  }

标签: angularsharepointhttpclient

解决方案


谢谢,@ user2457680。

我将发布我的代码最终如何解决我的问题。我希望,其他人会觉得它有用。

getExpediente(): Observable<IExpediente> {
    return this.http.get<D>(this.urlSharepointAPIExpedientes, {
      headers: {
        accept: 'application/json;odata=verbose'
      }
    }).pipe(
      map(x => this.mapExpedientesOfObserver(x) ),
      expand(x => (x.Next ? this.getExpedienteFromUrl(x.Next) : EMPTY)),
      concatMap(x => x.Expedientes)
    );
  }

  private getExpedienteFromUrl(httpUrl: string): Observable<ExpedienteListAndNextQuery> {
    return this.http.get<D>(httpUrl, {
      headers: {
        accept: 'application/json;odata=verbose'
      }
    }).pipe(
      map(x => this.mapExpedientesOfObserver(x))
    );
  }

export interface D {
  d: Results;
}

export interface Results {
  results: SharepointExpediente[];
  __next: string;
}

Map 功能仅在 SharePoint 喜欢使用 word_x020_word_x020_word 之后将 SharePoint 变量转换为类似人类的变量,无论是为自己还是为他人维护都将是一场噩梦。


推荐阅读