【问题标题】:Angular 5 RxJs concatMap,switchMap,mergeMap which?Angular 5 RxJs concatMap,switchMap,mergeMap 哪个?
【发布时间】:2022-02-19 23:18:41
【问题描述】:

我有这个方法通过localstorage获取token,如果token不存在或者过期,我会调用API获取另一个token并存储到localstorage。

在这种情况下,我应该使用哪个地图,当前使用的是 mergeMap,还是其他方式?

public doGetToken():Observable<Token> {
    return this.loadToken().pipe( //get via localstorage
      map(token=>{
        let valid = this.validateTokenIsValid(token);
        let data = {
          token: token,
          valid: valid
        };
        return data;
      }),
      mergeMap(data=>{
        if (!data.valid) {
          return this.doApiGetToken(data.token).pipe(
            map(
              token=>{
                this.saveToken(token); //save to localstorage
                return token;
              }
            )
          );
        } else {
          return of(data.token);
        }
      })
    );

版本:Angular 5,rxjs5

提前谢谢你。

【问题讨论】:

    标签: angular angular5 rxjs5 angular-local-storage


    【解决方案1】:

    如果您只提出一个请求,那么没关系您使用哪张地图。

    mergeMap(也称为 flatMap)、concatMap、exhaustMap 或 switchMap 的行为相同。

    当您发出超过 1 个值时,这些运算符的行为会有所不同:

    switchMap

    将映射应用到收到的最新输入:

    Src : -----A----B----C--D-E-------
    
    switchMap (x => x--x) // emit x twice when received
    
    Out:  ------A--A-B--B-C-D-E--E----
    

    concatMap

    将在接受另一个输入之前完成映射:

    Src : -----A----B----C--D-E-----------
    
    concatMap (x => x--x) // emit x twice when received
    
    Out:  ------A--A-B--B-C--C--D--D-E--E
    

    合并地图

    类似于 concatMap,但它不等待映射完成。结果可能会重叠:

    Src : -----A----B----C-D---E-----------
    
    mergeMap (x => x--x) // emit x twice when received
    
    Out:  ------A--A-B--B-C-D-C-D-E--E-----
    

    exhaustMap

    就像一个反转的switchMap,它优先输出:

    Src : -----A--------B----C-D---E-----------
    
    exhaustMap (x => x--x--x) // emit x thrice when received
    
    Out:  ------A--A--A--B--B--B-D--D--D-------
    

    更多信息:

    https://medium.com/@vdsabev/the-simple-difference-between-rxjs-switchmap-and-mergemap-397c311552a5

    大理石图:

    http://rxmarbles.com/#mergeMap

    编辑:我将您的代码的简化移至底部,以使一般信息一目了然。

    public doGetToken(): Observable<Token> {
      return this.loadToken()
        .pipe( //get via localstorage
          mergeMap(token => {
            if(!this.validateTokenIsValid(token))
              return of(token)
            return this.doApiGetToken(token)
              .pipe(
                tap( token => this.saveToken(token)) //save to localstorage
              );
          })
        )
    };
    

    【讨论】:

      【解决方案2】:

      单源 observables 上述操作符没有区别。

      switchMap: 发出值并且只对它发送的最后一个值感兴趣。之前调用的所有响应都会被忽略。

      concatMap: 的行为类似于队列:它存储所有调用并一个接一个地发送。如果一个已完成,则正在处理下一个。

      mergeMap: 也发送所有请求,如 concatMap 但不等到响应返回。当他们来的时候,它就会把他们送出去。但它会收到每一个响应,并且不会忽略任何东西。这里的顺序不保证。

      exhaustMap: 发出第一个请求并忽略所有未来的请求,直到第一个请求返回。然后它就可以准备新的了。

      请参考此链接。真的很棒

      https://offering.solutions/blog/articles/2021/03/08/switchmap-mergemap-concatmap-exhaustmap-explained/

      【讨论】:

        猜你喜欢
        • 2018-09-16
        • 1970-01-01
        • 2019-01-31
        • 2018-07-31
        • 2018-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-22
        相关资源
        最近更新 更多