【问题标题】:Fire and forget in an Observable chain with RxJS使用 RxJS 在 Observable 链中触发并忘记
【发布时间】:2020-01-31 16:50:47
【问题描述】:

假设我有 2 个函数,每个函数返回一个 Observable

  • getUsersDataObs():返回的 Observable 调用一个 http 端点来获取一些与应用用户相关的数据,当接收到数据时这个 Observable 会发出
  • sendMailObs:返回的 Observable 调用邮件服务器发送电子邮件,当邮件服务器响应确认时,此 Observable 发出

我需要用户数据来创建邮件,所以我需要先调用getUsersDataObs,然后再调用sendMailObs。同时我不需要知道sendMailObs 是否完成。我只想用“即发即弃”的策略发送邮件。

到目前为止我制定的解决方案是这样的

getUsersDataObs().pipe(
   tap(data => sendMailObs(data).subscribe())
)
.subscribe()

虽然这可行,但我们在订阅中有订阅,这通常看起来不太酷。同时,考虑到我想要的是“一劳永逸”,也许订阅中的订阅是合适的做法。

对此的任何评论将不胜感激

【问题讨论】:

  • 您可以将sendMailObs(data) 合并到链中并忽略其所有排放。

标签: rxjs


【解决方案1】:

除非您不必等待sendMailObs(data) 来合并其数据,否则此策略并没有什么不好。您可以将sendMailObs(data).subscribe() 视为getUsersDataObs() 的副作用。这确实是给定上下文中的副作用。

【讨论】:

    【解决方案2】:

    订阅内订阅的缺点之一是正确取消订阅两者确实具有挑战性。考虑改用高阶映射运算符。

    类似这样的:

      selectedProductSuppliers$ = this.selectedProduct$
        .pipe(
          filter(selectedProduct => Boolean(selectedProduct)),
          switchMap(selectedProduct =>
            forkJoin(selectedProduct.supplierIds.map(supplierId => this.http.get<Supplier>(`${this.suppliersUrl}/${supplierId}`)))
          )
        );
    

    当第一个 Observable (this.selectedProduct$) 发出时,它会过滤掉任何空值(没有选择任何产品)。然后它使用 switchMap(一个高阶映射运算符)来处理内部订阅。

    所以你的代码看起来更像这样:

    getUsersDataObs().pipe(
       switchMap(data => sendMailObs(data))
    )
    .subscribe()
    

    我有一个 stackblitz 示例,它获取用户,然后在此处获取用户的待办事项:https://stackblitz.com/edit/angular-todos-deborahk-switchmap

    this.todosForUser$ = this.http.get<User[]>(url)
      .pipe(
        switchMap(user =>
          this.http.get<ToDo[]>(`${this.todoUrl}?userId=${this.currentUserId}`)
        )
      );
    

    【讨论】:

    • 我同意管理unsubscribe 的观点。同时,在我的例子中,嵌入式订阅来自“just one shot” Observable,它在第一个通知被触发时完成。所以退订不是我的问题。我想要的是一个尝试发送邮件并且不等待任何成功或错误通知的逻辑。使用switchMap 似乎暗示我必须等待收到响应才能完成外部Observable,这不是我想要的。
    猜你喜欢
    • 1970-01-01
    • 2014-12-06
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2023-03-09
    • 2021-12-13
    • 1970-01-01
    相关资源
    最近更新 更多