Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular concatMap和share只播放一次一系列可观察到的内容,即使有多个订户_Angular_Typescript_Rxjs - Fatal编程技术网

Angular concatMap和share只播放一次一系列可观察到的内容,即使有多个订户

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

我正在尝试执行一些串联的观察,这是我用concatMap完成的,但我希望它们只执行一次,即使我有多个订户,我尝试了share和shareReplay操作符,但它们似乎都不起作用

代码如下:

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,则不会再次执行观测值,不会在每个订阅上计算变量,这就是我要寻找的。