Angular RxJS正在寻找类似于;延迟至;
我有两个函数,一个返回Angular RxJS正在寻找类似于;延迟至;,angular,typescript,rxjs,reactive-programming,Angular,Typescript,Rxjs,Reactive Programming,我有两个函数,一个返回observableea,另一个返回observableeb。我希望getter和订阅observableB延迟到observableea完成(但当我订阅observableeb时,observableea已经完成,情况也可能如此) 我已经尝试过使用pipe和skipUntil,但不幸的是,如果observatea尚未完成,这只会阻止执行,而不会延迟执行 functionA(){ this.observableea$=getobservableea() 此.observeE
observableea
,另一个返回observableeb
。我希望getter和订阅observableB
延迟到observableea
完成(但当我订阅observableeb
时,observableea
已经完成,情况也可能如此)
我已经尝试过使用pipe
和skipUntil
,但不幸的是,如果observatea
尚未完成,这只会阻止执行,而不会延迟执行
functionA(){
this.observableea$=getobservableea()
此.observeEA$.subscribe(=>{
//A:此行应在*行B之前执行*
})
}
函数b(){
this.observableB$=getObservableB()//此getter应在*行A之后执行*
此.observableB$.subscribe(=>{
//B:这一行应该在A行之后执行
})
}
//两个函数分别被调用
函数()
函数b()
如果能找到一种非常RxJS风格的方式,那就太好了:)
更新1:concat的问题:: 如上所述,这两个函数都是独立调用的,这将导致在使用建议的
concat
时重复执行observableea$
。另外,functionB
中的订阅将执行两次我不想要的操作
functionA(){
this.observableea$=getobservableea()
此.observeEA$.subscribe(=>{
//A:此行应在*行B之前执行*
})
}
函数b(){
可观察的(
this.observeEA$,//我再次执行:(
Observable.defer(()=>getObservableB())//防止更早执行
).订阅(()=>{
//B:这一行应该在A行之后执行
log(“我记录了两次,每次观察一次:(”)
})
}
//两个函数分别被调用
函数()
函数b()
更新2:@Wilhelm Olejnik通过使用另一个
行为主体解决了这个问题
我遇到了一个类似的情况,我创建了一个服务SyncService
来同步观测值。对我来说,ObsA
和ObsB
来自不同的组件。组件a
得到了一些我的支持组件B
加载其自身数据后所需的初始化数据
在ComponentA
中,我订阅了ObsA
(从getInitData()
返回)并调用了同步服务:
public initialize() {
this.apiSvc.getInitData().subscribe((initData) => {
this.data = initData;
this.syncService.setA(initData);
}
}
public loadBData() {
this.apiSvc.getBData().subscribe((dataB) => {
this.syncService.setB(dataB).subscribe((dataA, dataB) => {
this.doStuffWithAAndB(dataA, dataB);
}
}
}
然后,在ComponentB
中,我订阅ObsB
(从getBData()
返回),然后订阅同步服务:
public initialize() {
this.apiSvc.getInitData().subscribe((initData) => {
this.data = initData;
this.syncService.setA(initData);
}
}
public loadBData() {
this.apiSvc.getBData().subscribe((dataB) => {
this.syncService.setB(dataB).subscribe((dataA, dataB) => {
this.doStuffWithAAndB(dataA, dataB);
}
}
}
最后,同步服务如下所示:
@Injectable
export class SyncService {
private dataA: DataA = null;
private dataB: DataB = null;
private gotAEvent: new EventEmitter<DataA>();
public setA(dataA: DataA) {
this.dataA = dataA;
if (this.dataB != null) {
// ObsB was already resolved!
this.gotAEvent.emit(dataA);
}
}
public setB(dataB: DataB) {
this.dataB = dataB;
if (this.dataA != null) {
return of({this.dataA, this.dataB});
} else {
return this.gotAEvent().map((dataA: DataA) => {
return {dataA, dataB};
}
}
}
}
@可注入
导出类同步服务{
私有dataA:dataA=null;
私有数据:dataB=null;
private gotAEvent:new EventEmitter();
公共setA(dataA:dataA){
this.dataA=dataA;
如果(this.dataB!=null){
//ObsB已经解决了!
this.gotAEvent.emit(dataA);
}
}
公共教育部(数据库:数据库){
this.dataB=dataB;
如果(this.dataA!=null){
返回({this.dataA,this.dataB});
}否则{
返回此.gotAEvent().map((dataA:dataA)=>{
返回{dataA,dataB};
}
}
}
}
如果我理解正确,您希望延迟getObservableB
执行,直到将某个可观察对象分配给属性observableea$
也许使用一些代理
技巧是可行的,但我认为将observableea$
更改为null initializedBehaviorSubject
更容易。然后您可以观察observableea$
并在发出非null信号时创建observableeb$
从'rxjs'导入{of,BehaviorSubject,timer};
从“rxjs/operators”导入{filter、switchMap、mapTo、tap};
const getobserveea=()=>计时器(100).pipe(
轻触(()=>console.log('getobserveea'),
映射到('A')
);
const getObservableB=()=>计时器(100).pipe(
轻触(()=>console.log('getObservableB')),
映射到('B')
);
课堂测试{
//init observeEA$作为状态为null的行为主体
observableA$=新行为主体(空);
可观测EB$;
函数(){
getObservableA().subscribe(val=>{
console.log(val)
this.observeea$.next(val);//通知订阅者observeea$已准备就绪
});
}
函数b(){
this.observableB$=this.observableA$.pipe(
筛选器(value=>value!==null),//在初始化之前忽略observableA$
switchMap(值=>getObservableB())
)
此.observableB$.subscribe(console.log)
}
}
常量测试=新测试();
test.functionB();
setTimeout(()=>test.function(),500);
//Getobservea
//A
//getObservableB
//B
看看concat或concatMap操作符。我已经用一个例子更新了我的答案,说明了为什么concat
不起作用。(或者至少不适用于我如何使用它。)这太完美了。非常感谢。行为主体
成功了。