withLatestFrom运算符不会在空值上打勾 [英] withLatestFrom operator does not tick on null value

查看:107
本文介绍了withLatestFrom运算符不会在空值上打勾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用@ngrx/effect的Angular项目中,使用withLatestFrom rxjs运算符可以观察到流.

这是我们可观察到的效果流:

@Effect()
handleUsersData$ = this.actions$
.pipe(
    ofType(HANDLE_USER_DATA),
    withLatestFrom(
      this.store.pipe(select(getCurrentUserId)),
      this.store.pipe(select(getUserEntities)),
    ),
    tap(([action, currentUserId, users]) => console.log(([action, currentUserId, users]))),
    switchMap(([action, currentUserId, users]) => {
      const dispatchedActions: Action[] = [];

      if (currentUserId) {
        dispatchedActions.push(new SetCurrentUser()); 
      } else {
        dispatchedActions.push(new SomeAction());
        dispatchedActions.push(new ClearUsers());
      }

      return dispatchedActions;
    })
);

我们使用的选择器之一是:

export const getCurrentUserId = createSelector(
  getUserEntities,
  getRouterStateUrl,
  (users: Dictionary<User>, router: RouterStateUrl) => {

    return router.params && users[router.params.userId] || null;
  }
);

定义userId后,将正确分派动作. console.log显示用户ID和用户实体.

但是,如果userId不在路由器参数中,则选择器将返回null,并且可观察到的流将永远不会滴答. tap中的console.log不返回任何内容`

为什么withLatestFrom似乎忽略了null值,并且如果此值是选择器的结果,只是不打勾?在我们的上下文中,这是一个有效值.

即使getCurrentUserId选择器中存在空值,如何确保可观察的流滴答作响?

解决方案

您似乎想改用combineLatest.

withLatestFrom不会忽略null.这是常规值.但是,withLatestFrom仅对直接来源的排放做出反应.这是来自this.actions$.pipe(ofType(HANDLE_USER_DATA)).它也保留了来自其他来源的排放,但仅将其保留在其内部缓冲区中,而对它们没有反应.

另一方面,combineLatest将在每个源发出的所有发射中发出,所有它们都发出至少一个项目后才可观察到(如果要确保所有源至少发出一次,请查看startWith). /p>

In an Angular project using @ngrx/effect we have an observable stream using withLatestFrom rxjs operator.

Here is our observable effect stream:

@Effect()
handleUsersData$ = this.actions$
.pipe(
    ofType(HANDLE_USER_DATA),
    withLatestFrom(
      this.store.pipe(select(getCurrentUserId)),
      this.store.pipe(select(getUserEntities)),
    ),
    tap(([action, currentUserId, users]) => console.log(([action, currentUserId, users]))),
    switchMap(([action, currentUserId, users]) => {
      const dispatchedActions: Action[] = [];

      if (currentUserId) {
        dispatchedActions.push(new SetCurrentUser()); 
      } else {
        dispatchedActions.push(new SomeAction());
        dispatchedActions.push(new ClearUsers());
      }

      return dispatchedActions;
    })
);

One of the selectors we use is the following:

export const getCurrentUserId = createSelector(
  getUserEntities,
  getRouterStateUrl,
  (users: Dictionary<User>, router: RouterStateUrl) => {

    return router.params && users[router.params.userId] || null;
  }
);

When userId is defined, the actions are dispatched properly. The console.log displays user ID and users entities.

But if userId is not among router params, the selector returns null and the observable stream never ticks. console.log in the tap returns nothing`

Why does withLatestFrom seems to ignore null value and just not tick if this value is the result of the selector? It's a valid value in our context.

How to ensure that the observable stream ticks even if there is a null value in getCurrentUserId selector?

解决方案

It looks like you want to use combineLatest instead.

withLatestFrom doesn't ignore null. It's a regular value. However, withLatestFrom reacts only on emissions from its direct source. That's from this.actions$.pipe(ofType(HANDLE_USER_DATA)). It keeps emissions from other sources as well but it only keeps them in its internal buffer and doesn't react to them.

On the other hand combineLatest will emit on every emission from every source Observable after they all emit at least one item (have a look at startWith if you want to be sure all sources emit at least once).

这篇关于withLatestFrom运算符不会在空值上打勾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆