【问题标题】:Get Last Value from Observable in Angular 8从 Angular 8 中的 Observable 获取最后一个值
【发布时间】:2020-05-28 21:15:49
【问题描述】:

如何从 Angular 8 中的 Observable 中获取最后一个值?

let test = new BehaviorSubject<any>('');
test.next(this.AddressObservable);

let lastValue = test.subscribe(data=>console.log(data.value));

由于某种原因它不工作,检查调试器。

但是,这是在 html 中工作的,AddressObservable | async

尝试使用此链接,希望将值存储在变量中或显示在控制台日志中。任何较新的语法都会有所帮助。

How to get last value when subscribing to an Observable?

注意:

AddressObservable 的类型为:Observable&lt;AddressDto&gt;

【问题讨论】:

  • 您的代码看起来有点混乱。您正在使用字符串初始化一个行为主体,然后通过该主体发出另一个可观察对象。您可以发布相关代码以提供此帖子上下文

标签: angular typescript rxjs observable angular8


【解决方案1】:

您在这里的行为主题以及它对您的作用有点混淆。

主题实际上是您可以订阅的某个来源的值流。每当发出新值时,它都会到达您的 subscribe 方法。

如果你有初始状态,你可以使用行为主体来初始化主体并确保新订阅者总是收到一个值。

如果您没有初始状态,但想确保新订阅者在订阅时获得最后发出的值(如果存在),那么您可以使用重播主题。

进入一个主题的所有值都是类型 T,你有Subject&lt;T&gt;。所以在你的情况下,进入主题的所有内容都应该是AddressDto

如果你有一个初始地址,那么你可以这样设置你的行为主题:

// somehow get my initial address
const address = new AddressDto(); //
const test = new BehaviorSubject<AddressDto>(address);

// all subscribers will receive this address upon subscribing

// ... some things happen

// now I have another address, emit that
const newAddress = new AddressDto();
test.next(newAddress);

// all new subscribers will now receive newAddress upon subscribing

另一方面,如果您没有初始地址,则可以使用这样的重播主题:

// always emit the last address to new subscribers by intitialing with a 1
// New subscribers won't receive an address until one is emitted
const test = new ReplaySubject<AddressDto>(1);

// ... some things happen

// now I have my first address, emit that
const firstAddress = new AddressDto();
test.next(firstAddress);

// all current subscribers receive firstAddress
// all future subscribers will receive firstAddress upon subscribing

// ... some things happen

const secondAddress = new AddressDto();
test.next(secondAddress);

// all current subscribers receive secondAddress
// all future subscribers will now receive secondAddress upon subscribing

编辑:

您已经询问了将最后一个值存储在变量中的问题。你的意思是模棱两可的,所以我假设你的意思是源头,因为那更复杂。

一旦您了解了主题/可观察的概念,您就会开始了解可观察管道的概念。各种各样的事情都可能发生在管道内——只要把它想象成一系列可能发生在一个对象上的事情的步骤,就像一个普通的 javascript 数组上的一系列链式数组函数。

您可以在管道中做的一件事是在tap() 运算符中执行“副作用”。这只是意味着您可以在管道中间做一些事情,同时让数据通过。其中之一可能是出于某种目的将值存储在变量(或本地存储或其他)中。

如果您可以控制主题中的内容,那么在管道中执行此操作似乎是多余的,因此我将使用缓存 http 请求结果的示例。

this.http.get(url).pipe(
  // transform the http response into an object you have created
  map(response => this.mapResponseToMyClass(response)),
  // store the mapped object in a local property for later use
  tap(myClass => {
    // you can perform any side-effect actions you want here
    console.log(myClass);
    // store the value in a variable
    this.cachedMyClass = myClass;
  })
);

为您自己的主题提供管道也没有什么不同 - 进入主题的所有内容都将通过管道,然后传递给订阅者。

private subject = new Subject<AddressDto>();

getPostcode(): Observable<string> {
  // reuse the local subject. All subscribers to this function will receive addresses that have come through the pipe.
  return subject.pipe(
    map(address => address.postcode),
    // store the last postcode in a local property
    tap(postcode => this.lastPostcode = postcode)
    // the postcode still comes out here to all subscribers
  ).asObservable();
}

【讨论】:

  • 好的,如何在执行下一步后将最后一个 dto 的值存储在变量中?或显示在控制台日志中?尝试正确设置订阅,谢谢
  • 也看不到上面链接到 AddressObservable 的主题
  • 需要链接到可观察和订阅示例会有帮助
  • 不确定您的意思,所以我添加了一个示例,说明如何登录到控制台并存储到本地变量。有很多关于使用 observables 和管道的教程比这更好,但我很感激一开始可能有点不知所措
  • 这是一个很有帮助的答案 - ty
【解决方案2】:

Observable 不存储值。在您将数据推送到 Observable 流中以接收值之前,您应该已经订阅了 Observable。我认为您的 AddressObservable 是 Observable,而不是 BehaviorSubject。如果将 AddressObservable 转换为 BehaviorSubject。它会起作用的。如果 AsyncPipe 它正在工作,因为它异步管道订阅相同。

将 AddressObservable 更改为类型:BehaviorSubject

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 2020-12-19
    • 1970-01-01
    • 2019-03-09
    • 2016-05-30
    • 2023-03-07
    • 2020-05-04
    相关资源
    最近更新 更多