Angular concatMap和share只播放一次一系列可观察到的内容,即使有多个订户
我正在尝试执行一些串联的观察,这是我用concatMap完成的,但我希望它们只执行一次,即使我有多个订户,我尝试了share和shareReplay操作符,但它们似乎都不起作用 代码如下:Angular concatMap和share只播放一次一系列可观察到的内容,即使有多个订户,angular,typescript,rxjs,Angular,Typescript,Rxjs,我正在尝试执行一些串联的观察,这是我用concatMap完成的,但我希望它们只执行一次,即使我有多个订户,我尝试了share和shareReplay操作符,但它们似乎都不起作用 代码如下: import{EMPTY,Observable,BehaviorSubject,of,from,concat,timer}来自'rxjs'; 从“rxjs/operators”导入{concatMap、map、switchMap、tap、filter、take、share、shareReplay、detain
import{EMPTY,Observable,BehaviorSubject,of,from,concat,timer}来自'rxjs';
从“rxjs/operators”导入{concatMap、map、switchMap、tap、filter、take、share、shareReplay、detain、publishLast、refCount};
常量刷新访问令牌=()=>{
log(“启动刷新访问令牌”)
返回计时器(2000);
}
常量连接=()=>{
日志(“启动连接”)
返回计时器(3000)
}
const authent=()=>{
日志(“启动授权”)
返回计时器(2000)
}
让isAuthenticated=false;
让isExpired=true;
函数initSocket():可观察
结果如下:
Start refresh access token
Start refresh access token
Start connect
Start connect
Start authent
Start authent
Tap
Finished 1
Tap
Finished 2
但我要找的是:
Start refresh access token
Start connect
Start authent
Tap
Finished 1
Finished 2
也许这已经得到了回答,但我看不出我遗漏了什么,如果有人能帮忙,那就太好了
编辑:
我会解释我的需要,也许我解决问题的方法不对。
我正在编写一个封装socket.io客户机的服务类,该类中发出或侦听socket.io事件的每个函数都必须检查我们是否连接到socket.io并通过身份验证
以下是每个订阅上的多个观测值需要做的事情:
检查是否已连接
如果不是,请检查访问令牌是否仍然有效
有效,如果是,请转到4
如果没有,请刷新访问令牌
创建socket.io连接并等待connect事件
在连接事件上发送访问令牌并等待响应
如果身份验证成功,则继续下一次观察
在这一系列可观察对象中,第一个订户将执行所有可观察对象,如果第二个订户在可观察对象执行等待相同结果时到达,则不要两次启动连接
如果第三个或更多的用户在连接完成后到达,我们仍然需要检查变量是否已通过身份验证更改,如果为false,则像第一个订户一样,如果为true,则继续
希望这有助于澄清我在寻找什么。您希望将数据分配给一个可观察对象,然后订阅该可观察对象,而不是调用initFunction()
,它创建的可观察对象数量与订阅方的数量一样多。但是,通过将数据分配给可观察对象并订阅该数据,可以防止这种情况发生,还可以使用shareReplay
:
让obs$=newobservable();
函数initSocket():void{
如果(!已验证){
设可观测$=of(1);
如果(i已支出){
可观测$=refreshAccessToken();
}
obs$=可观测$管道(
concatMap(()=>connect()),
concatMap(()=>authent()),
点击(()=>{
isAuthenticated=true;
控制台日志(“点击”)
}),
shareReplay()
);
}
}
initSocket();
obs$.subscribe(()=>console.log(“完成1”))
obs$.subscribe(()=>console.log(“完成2”))
设置超时(()=>{
obs$.subscribe(()=>console.log(“20秒后完成3次”))
}, 20000)
stackblitz很好,但问题本身应该包括一个问题。如果(…当)链接死了,这个问题在将来就没用了。这是有效的。但不幸的是,这并不能解决我的问题,如果变量isAuthenticated为真,我不想重复整个过程,这个解决方案的问题是,如果我有另一个订阅者,比如说30秒后,身份验证会再次播放,这是不需要的。@Abdou,那么shareReplay()
呢?20秒后触发第三个订户:谢谢你的回答!它更好,但仍然缺少最后一部分,如果变量isAuthenticated更改为false,则不会再次执行观测值,不会在每个订阅上计算变量,这就是我要寻找的。