【发布时间】:2018-11-16 10:05:47
【问题描述】:
我需要:
- 依次发送 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
所以我想要的是在对象无效时不发送请求。并且我想从最初的 observable 处理 next id,前提是对先前的处理结束。所以我想要这样的流程:
- 第一个 id 上的 map + concatMap
- 第二个 id 上的 map + concatMap
- 还有更多更多更多...
我只通过扩展 concatMap 代码来处理这个问题。是否有可能在concatMap 之前将此检查提取到另一个可管道操作员?所以concatMap body 会更简单。
我尝试了 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 或 map 或任何其他运算符。在那一刻,当from(this.ids) 中发出新值时(它将在concatMap 完成之前)它会处理整个链:map + concatMap。我需要的是在concatMap 完成第一个处理之后,以某种方式说 rxjs 来处理第二个发出的值。然后它应该在 concatMap 处理完第二个 e t c 之后处理第三个发出的值。
这里有一个扩展的例子: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
如何更改我的 observable,使其如下所示:
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
【问题讨论】:
-
也许我不明白你想做什么,但你可以直接返回
throwError而不是empty()和concatMap将继续下一个项目。创建错误通知将释放链。 -
对不起,可能是我的错。我编辑了一些问题。当 observable 因错误完成时就可以了。这就是我需要的。请检查我已编辑问题的结尾部分。
-
这是我需要的:stackblitz.com/edit/angular-zjsuvu。有什么办法可以简化吗?
标签: angular rxjs httpclient concatmap