如何将可观察值传递给rxjs主题?

时间:2018-09-19 23:34:07

标签: angular rxjs observable behaviorsubject

我想从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;
  }
}

是否有任何方法可以返回主题并通过单个方法调用触发http调用?很奇怪,因为返回了主题,注册了订阅者,完成了http调用并调用了this.subject.next(res),但是订阅处理程序甚至没有运行。

4 个答案:

答案 0 :(得分:1)

Pierre,发生这种情况的原因是, AsyncSubject仅在可观察的完成 (由Subject.prototype.complete()确定)时才发出最后一个值。

在您的情况下,您可能希望使用BehaviorSubject来为订阅者使用流中的最后一个值,而与完成无关:

  

AsyncSubject发出最后发出的值(并且仅发出最后一个值)   仅在源可观察到之后   完成。 (如果源Observable没有发出任何值,则   AsyncSubject也会完成而不会发出任何值。)

Subject Documentation

更新:

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

答案 1 :(得分:1)

完成可观察性,它将起作用

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,在这种情况下,您需要处理空检查,因为BehaviourSubject需要默认值

public behaviourSub = new BehaviorSubject(null);

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

答案 2 :(得分:1)

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

由于AsyncSubject扩展了Observable,所以没有必要,但是我建议您使用“ 返回this.subject.asObservable()”,它是“ Subject”对象的一部分。由于您需要在其他类型的主题上使用它,因此,例如,如果通过 BehaviourSubject 更改主题的类型,则无需更改代码;)

答案 3 :(得分:0)

订阅视图中的“主题”以免获取。而且也无需从服务中退还该主题。

视图:

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

服务: 导出类ConfigService {

  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);
    });
  }
}