【问题标题】:How to subscribe to an observable once?如何订阅一次可观察对象?
【发布时间】:2020-09-16 12:34:28
【问题描述】:

我的函数access() 每次调用都需要订阅一次。

在下面的 sn-p 中,$valueChanges 为所做的每个更改发出数据。在没有const $ = ...$.unsubscribe() 的情况下调用access()$valueChanges observable 会发出不必要的值流。

是否有一个 rxjs 运算符/函数在函数内部的订阅中发出一次?即使该函数被多次调用,订阅也会发出一次?

access() {
  const $ = $valueChanges.pipe(
    map((res) => 
      ...
    ),
  ).subscribe((res) => {

    ...

    $.unsubscribe();
  });
}

【问题讨论】:

  • 您的问题不清楚。您提供的代码将发出一次然后完成,无需取消订阅,除非您向of() 发送多个参数。查看文档here。如果您有更复杂的代码可能使用不同的 observable,请更新您的问题。请注意here 讨论的“完整”要求。
  • @dmcgrandle 是的,我将 of() 运算符更改为一些 valueChanges observable,它会在值更改时发出值。
  • 然后更改问题的详细信息以显示您实际做了什么。到目前为止,您给出的内容没有您所描述的问题。更好的是,设置一个StackBlitz 来显示正在发生的问题。
  • 感谢您提供更多信息。 $valueChanges 是否是一个热的可观察对象,无论是否订阅,它都一直在发射?如果是这样,当您调用access() 时,您是否希望$ 立即发出$valueChanges 发出的最后一个值(只要是过去),还是要等待@ 发出的下一个值987654339@,发出那个然后完成?
  • $valueChangesBehaviorSubject(文档here)?

标签: javascript angular reactjs typescript rxjs


【解决方案1】:

试试shareReply(1)。然后原始流将只被调用一次,它的发射将与所有订阅者共享。如果流第二次发出 - 更新也将发送给所有订阅者。

access() {
  const $ = $valueChanges.pipe(
    map((res) => 
      ...
    ),
    // take(1), // in case if you need just 1 emit from it.
    shareReply(1), // in case if you don't want to trigger `$valueChanges` on every subscription.
  ).subscribe((res) => {

    ...

    // $.unsubscribe(); // it's useless in case of `take(1)`.
  });
}

【讨论】:

    【解决方案2】:

    您可以考虑使用take() 运算符,并在完成之前只发出第一个值。

    根据documentationtake 运算符

    Emit provided number of values before completing.
    

    你可以这样使用它:

    access() {
      valueChanges
        .pipe(
          map((res) => 
            ...
          ),
          take(1),
        ).subscribe((res) => {
    
          ...
    
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-23
      • 2021-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多