Javascript 从EventEmitter可观察到的热的和共享的

Javascript 从EventEmitter可观察到的热的和共享的,javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,有没有办法从事件发射器(或Angular 2 alpha 46/RxJS 5 alpha中提供的同等产品)中获得热观测值?i、 e.如果我们在解析值后订阅,它将使用先前解析的值触发。就像我们总是回报同样的承诺一样 理想情况下,只使用Angular 2对象(我在某个地方读到,稍后会嵌入一个轻型RxJS以删除依赖项),否则导入RxJS就可以了。AsyncSubject似乎符合我的需要,但它在RxJS 5 alpha中不可用 我尝试了以下方法,但没有成功(从未触发)。知道怎么用吗 let emitte

有没有办法从
事件发射器
(或Angular 2 alpha 46/RxJS 5 alpha中提供的同等产品)中获得热观测值?i、 e.如果我们在解析值后订阅,它将使用先前解析的值触发。就像我们总是回报同样的承诺一样

理想情况下,只使用Angular 2对象(我在某个地方读到,稍后会嵌入一个轻型RxJS以删除依赖项),否则导入RxJS就可以了。AsyncSubject似乎符合我的需要,但它在RxJS 5 alpha中不可用

我尝试了以下方法,但没有成功(从未触发)。知道怎么用吗

let emitter = new EventEmitter<MyObj>();
setTimeout(() => {emitter.next(new MyObj());});
this.observable = emitter;
return this.observable.share();
let emitter=new EventEmitter();
setTimeout(()=>{emitter.next(new MyObj());});
这。可观察=发射器;
返回此.observable.share();

Usecase:仅访问一些异步对象一次(例如,一系列合并/包装在
EventEmitter
中的HTTP调用),但将解析的异步对象提供给订阅它的任何服务/组件,即使它们在解析后订阅(HTTP响应被接收)

编辑:问题不在于如何合并HTTP响应,而在于如何从EventEmitter或Angular 2 alpha 46/RxJS 5 alpha提供的任何等效产品中获取(热?)可观测值,该产品允许在检索/解析异步结果后订阅(HTTP只是异步源的一个示例)MyEventMitter.share()不起作用(参见上面的plunker),尽管它可以处理HTTP返回的可观察对象(cf@Eric Martinez)。从Angular 2 alpha 46开始,.toRx()方法不再存在,EventEmitter是可观察对象和主体本身

只要我们总是返回相同的承诺对象,这一点在承诺中就可以很好地发挥作用。由于我们在HTTP Angular 2服务中引入了观察器,因此我希望避免将承诺和观察器混为一谈(据说观察器比承诺更强大,因此它应该允许用承诺做容易的事情)

(我还没有找到版本5 alpha的文档-Angular 2使用的版本)-正在处理Angular 2 HTTP服务返回的
Observable
,而没有处理EventEmitter

编辑:阐明了为什么不使用HTTP返回的Observable,并补充说不直接使用RxJS会更好

编辑:更改的描述:问题在于多个订阅,而不是合并HTTP结果


谢谢

您似乎描述的功能不是一个冷可观察的功能,而是一个
Rx.behavior subject
。在这里查看关于Rxjs主题的解释:

我在此引述:

行为主体与ReplaySubject类似,只是它只存储它发布的最后一个值。行为主体在初始化时还需要一个默认值。当受试者尚未收到其他值时,该值将发送给观察者。这意味着所有订阅者将在订阅时立即收到一个值,除非主题已经完成

Rx.AsyncSubject
在行为上最接近承诺:

AsyncSubject与Replay和Behavior主题类似,但是它只存储最后一个值,并且仅在序列完成时发布。当源可观察对象是热的并且可能在任何观察者订阅之前完成时,可以使用AsyncSubject类型。在这种情况下,AsyncSubject仍然可以提供最后一个值并将其发布给任何未来的订户

还有两条评论:

  • 在您的plunker中:
    this.\u coldObservable=emitter.share()。使用
    share
    返回一个热的可观察值
  • EventEmitter
    实际上首先扩展了主题
更新: 将EventEmitter包装在一个
Rx.Observable

function toRx ( eventEmitter ) {
  return Rx.Observable.create(function ( observer ) {
    eventEmitter.subscribe(function listener ( value ) {observer.onNext(value)});
    // Ideally you also manage error and completion, if that makes sense with Angular2
    return function () {
      /* manage end of subscription here */
    };
  };
)
}
一旦你有了可观察的
,你就可以随心所欲地应用
share()
shareReplay(1)


我打赌Angular团队迟早会提出一个Brigging函数,但如果你不想等待,你可以自己做。

ReplaySubject
正在做我想做的事情@robwormald在gitter I上提供了一个工作示例,为了更好地演示,对其进行了一些修改

公开HTTP响应:

多次订阅:


编辑:
BehaviorSubject
是另一个选项。在本用例中,差异是初始值,例如,如果我们想在使用HTTP响应进行更新之前显示缓存中的内容。

我有一个使用共享的HTTP示例。当您的用例使用Http模块时,为什么要询问将EventEmitter转换成什么?在我的描述中,这是一种误导,用例稍微复杂一些:一系列Http调用,一旦完成,我会将结果合并/包装到一个新的可观察对象中。与promises等价(角度1语法):
return$q.all(httpPromisesToResolve)我认为您不需要
共享()
来完成此任务。你需要的是。检查这一点实际上我更关心的是如何拥有多个订阅者,并且只触发HTTP请求/触发异步进程一次,而不管对结果进行了什么转换,尽管很高兴看到flatMap可以实现什么(我学到了,谢谢:))。@user3743222建议的AsyncSubject似乎就是解决方案,现在我正在检查如何在Angular 2中使用RxJS lib v.5 alpha。
share()
在HTTP返回的观察器上运行良好(我刚刚检查过,它正在运行,转换为热可观测),但在EventEmitter上不起作用。谢谢你的回答!似乎
AsyncSubject
就是我要找的,尽管Angular lib提供的对象会更好。但我没能找到
import {Injectable} from 'angular2/angular2';
import {Http} from 'angular2/http';
import {ReplaySubject} from '@reactivex/rxjs/dist/cjs/Rx'

@Injectable()
export class PeopleService {
  constructor(http:Http) {
    this.people = new ReplaySubject(1);

    http.get('api/people.json')
      .map(res => res.json())
      .subscribe(this.people);
  }
}
// ... annotations
export class App {
  constructor(peopleService:PeopleService) {

    people.subscribe(v => {
      console.log(v)
    });

    //some time later

    setTimeout(() => {
      people.subscribe(v => {
        console.log(v)
      });
      people.subscribe(v => {
        console.log(v)
      });
    },2000)
  }
}