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