如何 return 从单个 Observable<[]> 修改两个 Observable<[]>
How to return two modified Observable<[]> from a single Observable<[]>
我有一个 Observable<Person[]>
,其中 Person 界面如下所示:
export interface ToolfaceData {
age: number;
name: string;
}
我想创建两个 Observable<Person[]>
,其中一个将 2
添加到数组中所有 Person
的年龄,另一个从数组中减去 2
数组中所有 Person
的年龄。
如果这是流式传输给我的数据:
of (Person{age:2, name: Anne}, Person{age:5, name: Bob})
,然后我会创建两个 Observable<Person[]>
:
of (Person{age:4, name: Anne}, Person{age:7, name: Bob})
和
of (Person{age:0, name: Anne}, Person{age:3, name: Bob})
我该怎么做呢?
我尝试过的:
- 我已经尝试
tap
并发现当我只创建两个 observable 之一时,它可以工作,但是当我创建两个时,它们都是原始的 Observable(我不确定为什么会这样,但我想这不是我现在的主要问题)。
- 我已经尝试
map
但找不到在创建第一个 observable 时不修改原始数据的方法,这在我尝试创建第二个 observable 时会产生问题。
我不确定你的意图,但是...
tap
仅用于副作用,实际上它对可观察管道根本没有影响。它用于例如用于调试或记录。
map
用于将传递的值重新映射到另一个值。例如。你可以像 .pipe(map(person => Person{age: person + 2, name: person.name}))
这样给 Person 添加年龄
mergeMap
用于将传递的值重新映射到新的可观察对象,其值将传递到输出流。它用于例如对于异步 API 调用。
所以您尝试做的可能是这样的:
source$.pipe(
mergeMap(person => concat( // concat two observables
of(Person{age: person + 2, name: person.name}), // .pipe(...),
of(Person{age: person - 2, name: person.name}) // .pipe(...)
))
)
您可以将一个初始的 Observable 数据流分配给一个新的 observable 变量,使用管道运算符修改数据并单独订阅该值,而无需修改原始源数据。
我用地图函数给年龄加了2
const personObservable$ = of(
{
age: 2,
name: 'Anne',
},
{
age: 5,
name: 'Bob',
}
);
personObservable$.subscribe(person => console.log('Original', person));
const personAgePlus$ = personObservable$
.pipe(
map(({age, name}) => {
age = age + 2;
return {age, name};
})
).subscribe(person => console.log('Age +2', person));
const personAgeMinus$ = personObservable$
.pipe(
map(({age, name}) => {
age = age - 2;
return {age, name};
})
).subscribe(person => console.log('Age -2', person));
如果您希望从现有的可观察对象创建一个(或更多)可观察对象,您可以简单地将其定义为从原始对象开始,然后pipe()
排放到您想要的值。
因此,如果您的“原始”值如下所示:
people$ = this.service.getPeople();
您可以像这样定义其他可观察对象:
olderPeople$ = this.people$.pipe(
map(people => people.map(p => ({...p, age: p.age + 2})))
);
youngerPeople$ = this.people$.pipe(
map(people => people.map(p => ({...p, age: p.age - 2})))
);
这是一个有效的 StackBlitz 演示。
注意:如果多个 observables 来自同一来源,您可以将 shareReplay
应用于原始数据以防止底层逻辑(在这种情况下调用 getPeople()
) 从为每个订阅执行一次:
people$ = this.service.getPeople().pipe(shareReplay());
我有一个 Observable<Person[]>
,其中 Person 界面如下所示:
export interface ToolfaceData {
age: number;
name: string;
}
我想创建两个 Observable<Person[]>
,其中一个将 2
添加到数组中所有 Person
的年龄,另一个从数组中减去 2
数组中所有 Person
的年龄。
如果这是流式传输给我的数据:
of (Person{age:2, name: Anne}, Person{age:5, name: Bob})
,然后我会创建两个 Observable<Person[]>
:
of (Person{age:4, name: Anne}, Person{age:7, name: Bob})
和
of (Person{age:0, name: Anne}, Person{age:3, name: Bob})
我该怎么做呢?
我尝试过的:
- 我已经尝试
tap
并发现当我只创建两个 observable 之一时,它可以工作,但是当我创建两个时,它们都是原始的 Observable(我不确定为什么会这样,但我想这不是我现在的主要问题)。 - 我已经尝试
map
但找不到在创建第一个 observable 时不修改原始数据的方法,这在我尝试创建第二个 observable 时会产生问题。
我不确定你的意图,但是...
tap
仅用于副作用,实际上它对可观察管道根本没有影响。它用于例如用于调试或记录。
map
用于将传递的值重新映射到另一个值。例如。你可以像 .pipe(map(person => Person{age: person + 2, name: person.name}))
mergeMap
用于将传递的值重新映射到新的可观察对象,其值将传递到输出流。它用于例如对于异步 API 调用。
所以您尝试做的可能是这样的:
source$.pipe(
mergeMap(person => concat( // concat two observables
of(Person{age: person + 2, name: person.name}), // .pipe(...),
of(Person{age: person - 2, name: person.name}) // .pipe(...)
))
)
您可以将一个初始的 Observable 数据流分配给一个新的 observable 变量,使用管道运算符修改数据并单独订阅该值,而无需修改原始源数据。
我用地图函数给年龄加了2
const personObservable$ = of(
{
age: 2,
name: 'Anne',
},
{
age: 5,
name: 'Bob',
}
);
personObservable$.subscribe(person => console.log('Original', person));
const personAgePlus$ = personObservable$
.pipe(
map(({age, name}) => {
age = age + 2;
return {age, name};
})
).subscribe(person => console.log('Age +2', person));
const personAgeMinus$ = personObservable$
.pipe(
map(({age, name}) => {
age = age - 2;
return {age, name};
})
).subscribe(person => console.log('Age -2', person));
如果您希望从现有的可观察对象创建一个(或更多)可观察对象,您可以简单地将其定义为从原始对象开始,然后pipe()
排放到您想要的值。
因此,如果您的“原始”值如下所示:
people$ = this.service.getPeople();
您可以像这样定义其他可观察对象:
olderPeople$ = this.people$.pipe(
map(people => people.map(p => ({...p, age: p.age + 2})))
);
youngerPeople$ = this.people$.pipe(
map(people => people.map(p => ({...p, age: p.age - 2})))
);
这是一个有效的 StackBlitz 演示。
注意:如果多个 observables 来自同一来源,您可以将 shareReplay
应用于原始数据以防止底层逻辑(在这种情况下调用 getPeople()
) 从为每个订阅执行一次:
people$ = this.service.getPeople().pipe(shareReplay());