【问题标题】:RxJS 6 / When does tap operator emit a valueRxJS 6 /点击运算符何时发出值
【发布时间】:2019-04-16 09:25:44
【问题描述】:

我一直在想是否可以安全地假设在使用 tap 操作符之后,它内部的副作用已经完成。

我的用例是ngrx。

 ...
tap(() => {
    this.store.dispatch(new SetValue("Hello World"));
  }
}),
switchMap(() => this.store),
select(state => state.value),
tap(state => {
  if (state === undefined) {
    throw new Error("Couldn't find value");
  }
})

SetValue是一个实现ngrx的类

export class SetValue implements Action {
  readonly type = SET_VALUE;
  constructor(public payload: string) {}
}

我正在尝试实现的是在商店中设置一个值,然后检查它是否已有效设置。

我可以假设在点击操作符之后调度已经完成吗?

回答

我在 Angular Router guards 上使用它通过 url 上的参数设置初始状态,所以我最终过滤为仅在商店有新值时继续

 ...
tap(() => this.store.dispatch(new SetValue("Hello World"))),
switchMap(() => this.store),
select(state => state.value),
filter(value => value === "Hello World"),
take(1)

【问题讨论】:

  • 我对我的代码的思考过于迫切,我对任何遇到此问题的人的建议是鼓励反应式编程,考虑蒸汽以及何时发送数据

标签: rxjs ngrx rxjs5 rxjs6 ngrx-store


【解决方案1】:

RxJS 中的大多数操作都是同步的,所以如果 this.store.dispatch(new SetValue("Hello World")) 不执行任何异步任务,它可能会按预期工作(它仍然只是一个主题)。

但是,您不应依赖此行为。 NgRx 可能会改变它的内部结构,通常最好不要依赖 RxJS 运算符的同步/异步(这在过去已经发生过,例如 from() 从 RxJS 4 到 RxJS 5)。

如果您想确保已设置某些内容,请更改您的 new SetValue("Hello World") 效果以在完成所需操作后发出另一个操作。

【讨论】:

  • SetValue 是一个实现来自ngrx的动作的类,你的建议如何适应? export class SetValue implements Action { readonly type = SET_VALUE; constructor(public payload: string) {} }
  • 你可能会在另一个效果中处理这个动作,因为我猜你没有创建一个什么都不做的动作。因此,当它处理完 SetValue 动作后,您将其映射到另一个动作,告诉您 SetValue 已完成。
  • 我正在将问题编辑为现实世界的问题。我正在尝试使用基于 url 的 RouteGuard 为商店提供值。那是动作调度的地方。我想检查商店中的值是否已成功填写,否则重定向到另一个页面
  • 除了@martin 所说的,ngrx 也建议我们这样做。根据加载/设置操作发出成功/失败操作。然后,您可以收听由 Success/Fail 操作更新的加载/错误状态并决定离开。
  • 为了完整起见,我最终在点击旁边过滤(rxjs 过滤器运算符),以确保商店更改了值。
【解决方案2】:

tap 运算符接受 3 个参数。

1- 如果源 observable 发出一个值,tap 运算符的第一个参数是一个函数,该函数接收该发出的值作为参数。

2- 如果源 observable 进入错误状态,tap 运算符的第二个参数是一个接收该错误作为参数的函数。所以在这里你可以调度错误。

3- 第三个参数是一个函数,只要 observable 被标记为完成,就会调用该函数。

tap(observer, error, complete):Observable  

【讨论】:

    猜你喜欢
    • 2021-01-16
    • 2019-11-07
    • 2020-05-18
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多