1

我需要:

  • 依次发送 N 个请求(我使用 concatMap 来执行此操作)
  • 仅当对象有效时(我使用验证码扩展 concat 映射)
  • 在第一个错误时停止队列(通过服务器错误响应或客户端检查拒绝)

现在代码看起来像:

ids = [{valid: true, id: 1}, {valid: true, id: 2}, {valid: true, id: 3}, {valid: false, id: 4}]
constructor(httpClient: HttpClient) {
  from(this.ids)
  .pipe(
    map(obj => ({...obj, id: obj.id + 5})),
    concatMap(obj => {
      console.log('concat map');
      if (obj.valid === false) {
        return throwError('not valid');
      } else {
        return httpClient.get(`https://jsonplaceholder.typicode.com/todos/${obj.id}`);
      }
    })
  )
  .subscribe(
    result => console.log('success', result),
    result => console.log('error', result),
    () => console.log('complete')
  );
}

这是堆栈闪电战: https ://stackblitz.com/edit/angular-5vwbjg

所以我想要的是在对象无效时不发送请求。并且我想next从最初的 observable 处理 id,只有在处理先前的处理结束的情况下。所以我想要这样的流程:

  1. 第一个 id 上的 map + concatMap
  2. 第二个id上的map + concatMap
  3. 更多更多更多...

我只通过扩展 concatMap 代码来处理这个问题。是否有可能在concatMap? 所以concatMap身体会更简单。

我尝试了 mergeMap 运算符,例如:

mergeMap(obj => {
  console.log(obj);
  if (obj.valid === false) {
    return throwError('not valid');
  } else {
    return of(obj);
  }
}),

我在控制台中得到了这个:

在此处输入图像描述

这不是正确的结果。我预计 3 个请求,然后 1 个错误。预期结果:

在此处输入图像描述

在我的情况下,也许还有更漂亮的方式来描述检查功能?有任何想法吗?没有那个if有2个分支。

我认为我误解了这一点。from(this.ids)无论如何都会发出值。它不等待concatMap或映射或任何其他运算符。在那一刻,当新值发出时from(this.ids)(它将在concatMap完成之前),它会处理整个链:map+ concatMap。我需要的是在concatMap完成第一个处理后以某种方式说 rxjs 来处理第二个发出的值。concatMap然后它应该在处理完第二个等之后处理第三个发出的值。

一个扩展的例子在这里:https ://stackblitz.com/edit/angular-ovffm4?file=src/app/app.component.ts

在这里,我有 2 个客户端检查和 1 个服务器响应。

这是我在控制台中看到的:

map
first check true
second check 6
make request
map
first check true
second check 7
map
first check true
second check 8
map
first check true
second check 9
map
first check true
second check 10
map
first check false
success {userId: 1, id: 6, title: "qui ullam ratione quibusdam voluptatem quia omnis", completed: false}
make request
success {userId: 1, id: 7, title: "illo expedita consequatur quia in", completed: false}
complete

如何更改我的可观察对象,使其类似于:

map
first check true
second check 6
make request
success {userId: 1, id: 6, title: "qui ullam ratione quibusdam voluptatem quia omnis", completed: false}
map
first check true
second check 7
make request
success {userId: 1, id: 7, title: "illo expedita consequatur quia in", completed: false}
map
first check true
second check 8
map
first check true
second check 9
map
first check true
second check 10
map
first check false
complete
4

1 回答 1

0

对于初学者,我认为您误解了错误处理在 rxjs 中的工作原理。您作为第二个参数传递给订阅函数的错误处理函数永远不会被多次调用。一旦 observable 遇到一个错误,它就完成并且不再起作用。因此,您不能使用该函数来捕获多个错误。

http://reactivex.io/documentation/operators/subscribe.html

一个 Observable 调用这个方法来表明它未能生成预期的数据或遇到了一些其他错误。这会停止 Observable,并且不会进一步调用 onNext 或 onCompleted。onError 方法将导致错误的原因作为其参数(有时是 Exception 或 Throwable 之类的对象,有时是简单的字符串,具体取决于实现)。

您将永远无法以这种方式处理它。

这可能是另一种方式:

https://stackblitz.com/edit/angular-wbu3tv

片段:

  concatMap(obj => {
    console.log(obj);
    if (obj.valid === false) {
      return of({
          response: null,
          success: false
        });
    } else {
      return httpClient.get(`https://jsonplaceholder.typicode.com/todos/${obj.id}`).pipe(map(response => {
        return {
          response: response,
          success: true
        }
      }));
    }
  })

所以基本上,我没有使用 throwError,而是返回一个对象,该对象指示请求是否已执行,以及是否执行了响应。

于 2018-11-16T14:25:07.267 回答