我对不了解的RXJS Observables和管道有一些问题。
我的API返回这样的响应
{
"_embedded": {
"users": [
{
"id": 1,
"username": "steve"
}
]
}
}
我有以下功能(此问题非常简化):
listUsers() {
return this.http.get<Users>(API_BASE_URL + '/v1/users').pipe(map(u => u._embedded.users))
}
getFirstUser() {
return this.listUsers().pipe(first())
}
listUsersById() {
return this.listUsers().pipe(reduce((acc, user) => {
acc[user.id] = user
return acc
}, {}))
}
这是我的测试方式:
this.listUsers().subscribe(data => {
console.log("FUNC: listUsers()")
console.log(data)
console.log(data[0])
})
this.listUsersById().subscribe(data => {
console.log("FUNC: listUsersById()")
console.log(data)
console.log(data[0])
})
this.getFirstUser().subscribe(data => {
console.log("FUNC: getFirstUser()")
console.log(data)
})
listUsers()达到了我的期望,注销了11个用户对象的数组,然后注销了该数组中的第一个用户对象。
listUsersById()注销{undefined:[由11个用户对象组成的数组]},应该是一个哈希,其中键是id,值是用户对象。
getFirstUser()注销11个用户对象的数组(应该是一个)
问题似乎是rxjs并未将listUsers()的返回值视为“内部”数组,这使我的管道功能无法使用。
我想要的是创建“数据管道”,而无需解决功能,直到需要为止。使用返回承诺的Angular HTTPClient时,我应该如何正确执行此操作?
如果我解决了http请求,并且将数据放在一个数组中,则它可以正常工作。
from([
{
id: 1,
username: "steve"
},
{
id: 2,
username: "jane"
}
]).pipe(reduce((acc, user) => {
acc[user.id] = user
return acc
}, {}))
答案 0 :(得分:1)
正如@ jb-nizet在他的评论中解释的那样,该事件仅发出一次。
基于此,一种解决listUsersById()的简单实现方法是:
listUsersById() {
return this.listUsers().pipe(map(u => u.reduce((acc, user) => {
acc[user.id] = user
return acc
}, {})))
}
另一种选择是使用flatMap()为数组中的每个项目发出一个事件,如下所示:
listUsers() {
return this.http.get<Users>(API_BASE_URL + '/v1/users').pipe(map(u => u._embedded.users), flatMap(x => x))
}
通过这种方式,getUsersById()的原始实现可以按需工作,但就我而言,以这种方式进行操作毫无意义。