【问题标题】:How to handle an empty result with rxjs observable如何使用 rxjs observable 处理空结果
【发布时间】:2018-04-17 01:10:16
【问题描述】:

我有一个可能返回 [] 结果的 API。

HTTP/1.1 200 OK
Date: Tue, 16 Apr 2018 06:06:22 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
Request-Context: appId=cid-v1:...

[]

这是我在特定情况下不起作用的代码:

getData(): Observable<Thing[]> {
    return this.getData1()
    .pipe(
      flatMap(aData => {
        const ids = aData.map(({ id }) => id);
        const bData = this.getBData(ids); // emty result might be here

        //test subscribe
        this.getBData(ids).subscribe((data) => {
          //just had that for a test, to confirm subsscribe never fires when response is `[]`
          console.log(data);
        });

        return Observable.zip(
          Observable.of(aData),
          bData
        );
      }),
      // map does not executing when api that getting called by `this.getBData(ids)` returns `[]`
      map(([aData, bData]) => {
        // Merge the results
        const data: any = aData.concat(bData).reduce((acc, x) => {
          acc[x.scriptNumber] = Object.assign(acc[x.scriptNumber] || {}, x);
          return acc;
        }, {});
        return Object.values(data);
      })
    );
  }

this.getBData(ids);执行http调用,返回Observable&lt;Thing[]&gt;类型:

  getBData(ids):Observable<Thing[]> {
    const filters = {
      'id': [ids],
    };
    return this.http.post<Thing[]>('http://localhost:8080/api/thing', JSON.stringify(filters), {
      headers: new HttpHeaders().set('Content-Type', 'application/json')
    });
  }

我在控制台上没有错误。

处理这种情况的最佳做法是什么?

更新:

我确实更改了 api,所以现在它以这种方式返回数据:

HTTP/1.1 200 OK
Date: Tue, 17 Apr 2018 09:36:11 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
Request-Context: appId=cid-v1:...

{
  data: [],
  error: 'OK'
}

这样我总是有数据作为响应,我的代码只需稍作修改(aData.databData.data),但我仍然想知道为什么它在空数组的情况下没有工作,正如@DanielWSrimpel 评论它应该发出的那样无论如何都是一个值...?

【问题讨论】:

  • 一个空数组仍应在您的流上发出一个值。您是否尝试在订阅之前发现任何错误以查看是否发生了其他事情?
  • @DanielWSrimpel 并没有真正解决错误,但在控制台中看起来没有任何错误
  • @DanielWSrimpel 刚刚添加了更多细节(更新部分)
  • 那么,“测试订阅”块中的日志返回空数组?如果您删除该块,它会起作用吗?
  • @sreginogemoh,试图重现您的案例,stackblitz.com/edit/…。它有效

标签: angular rxjs observable


【解决方案1】:

首先,您的 post 方法(将空数组视为没有响应主体)或您的 API(返回空响应主体而不是空数组)存在问题,无论哪种方式,现在当您获取空数据时,它会只需完成请求,不返回任何内容。

其次,这个问题有一个解决方法(虽然我更喜欢像你一样将status字段添加到响应正文中),是使用RxJS toArray,如下所示:

this.getBData(ids)
    .pipe(toArray())
    .subscribe(([bData]) => {
      // Process the data
    });

注意:如您所见,toArray 发出一个包含 Observable 发出的所有项目的数组,这意味着在您的情况下,如果将返回一个空数组或一个包含您的数据数组的数组[[item1, item2]]

【讨论】:

    猜你喜欢
    • 2020-02-05
    • 2019-04-15
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 2020-10-06
    • 1970-01-01
    相关资源
    最近更新 更多