如何将可观察对象的值发送给 rxjs 主题?

How do I emit the value of an observable to an rxjs Subject?

我想从 Angular 服务提供一个 rxjs Subject,以便能够通过调用服务上的方法来发出值(通过 next)。我希望它发出的值之一是 Angular HttpClient get 调用的结果。我似乎无法做到正确。我想知道为什么以下结果导致未调用订阅处理程序:

-查看

export default abstract class TileView implements OnInit {
  constructor (private configService : ConfigService) {}
  ngOnInit () {
    this.configService.fetch(this.type()).subscribe( res => {
      console.log(res)
    }); 
  }
}

-服务

export class ConfigService {
  public subject = new AsyncSubject();

  constructor (private http : HttpClient) {}

  fetch (type) {
    this.http.get(
      api.host + api.base + interpolate(api.config, { type }) + "/"
    ).subscribe( res => {
      this.subject.next(res);
    });

    return this.subject;
  }
}

有什么方法可以 return 主题并通过单个方法调用触发 http 调用吗?这很奇怪,因为主题是 returned,订阅者已注册,http 调用完成并调用 this.subject.next(res) 但订阅处理程序甚至没有 运行.

订阅'subject'您认为不获取。也不需要 return 从您的服务中获取主题。

查看:

export default abstract class TileView implements OnInit {
  constructor (private configService : ConfigService) {}
  ngOnInit () {
    this.configService.subjectChanged(this.type()).subscribe( res => {
      console.log(res)
    }); 
  }
}

服务: 导出 class 配置服务 {

  public subjectChanged = new Subject();

  constructor (private http : HttpClient) {}

  fetch (type) {
    this.http.get(
      api.host + api.base + interpolate(api.config, { type }) + "/"
    ).subscribe( res => {
      this.subjectChanged.next(res);
    });
  }
}

Pierre,发生这种情况的原因是因为 AsyncSubject 仅在 observable completes 时发出最后一个值(由 Subject.prototype.complete()).

在您的情况下,您可能希望使用 BehaviorSubject,无论是否完成,它都会为订阅者发出流中的最后一个值:

An AsyncSubject emits the last value (and only the last value) emitted by the source Observable, and only after that source Observable completes. (If the source Observable does not emit any values, the AsyncSubject also completes without emitting any values.)

Subject Documentation

更新:

如果由于初始值传播而不愿意使用 BehaviorSubject,请使用 ReplaySubject(1)。

完成 observable,它将起作用

fetch (type) {
    this.http.get(
      api.host + api.base + interpolate(api.config, { type }) + "/"
    ).subscribe( res => {
      this.subject.next(res);
      this.subject.complete();
    });

    return this.subject;
  }

另一种方法是使用 BehaviourSubject,在这种情况下,您需要处理 null 检查,因为 BehaviourSubject 需要默认值

public behaviourSub = new BehaviorSubject(null);

this.configService.fetch(this.type()).subscribe( res => {
    if (res !== null) {
      // actual value emitted
    }
});

AsyncObservable 的特殊性之一是他在发送信息之前等待“complete()”完成

没有必要,因为 AsyncSubject 扩展了 Observable,但我建议您使用“return this.subject.asObservable()”,它是 "Subject" 对象。由于您需要在其他类型的主题上使用它,如果您通过 BehaviourSubject 更改您的主题类型,例如您将不需要更改您的代码 ;)