我怎样才能使用Observable而不是Promises?

时间:2017-08-02 16:44:31

标签: javascript angular promise es6-promise reactivex

我有一些使用某些方法的服务,大多数方法需要在完成某些操作之前完成某个回调。使用Promise,伪,很容易做到这一点:

ready = http.get(stuff); // Returns a promise, resolves after a while

methodOne() { // methods sometimes called before promise resolves
    this.ready.then(_ => { 
        // doStuff
    });
}

methodTwo() {
    return this.ready.then(d => {
        // doOtherStuff
    });
}

基本上我需要做的事情,只有当我确定服务准备好了。 我实际上只需要检查它是否已准备就绪(methodOne正在做什么,只是用methodTwo进行说明,以及更容易获得更多东西)。

我想试着全面了解Observables,但对于这个具体案例,我发现很难与Observables的类似解决方案竞争。

Promise会记住这个值并知道它是否得到了解决。 Observable有点复杂,似乎创建同样的流程很麻烦。我需要订阅Observable的任何东西,知道它什么时候准备就绪。有时候这个方法会在Observable发出之前提前调用,有时候会在Observable已经发出之后调用。

我现在有这个,但它似乎不起作用:

this.ready$ = someObservable // Will fire after a litle while but never finish - i only need the first to check though.
  .publishReplay(1).refCount(); // Trying to replay if subscription comes after emit.

this.ready$.subscribe(_ => {
    // This will be called
});

methodOne() { 
    this.ready$.subscribe(_ => {
        // Not called
    });
};

也许我误解了使用publishReplayrefCount

1 个答案:

答案 0 :(得分:3)

我认为您正在寻找的是AsyncSubject。它很好地模仿了承诺的行为。这是描述:

  

AsyncSubject是一个变体,只有最后一个值   可观察的执行被发送到它的观察者,并且只有在   执行完成。

以下是如何在您的情况下使用它:

subject = new AsyncSubject();
ready = streamOfData(stuff).first().subscribe(subject);    
methodOne() {
    return this.subject.asObservable();
}

主题订阅first运算符返回的基础observable并等待它完成。它收集所有订阅者但不向他们发送任何值。一旦底层的observable完成,它就会记住该值并将其发送给收集的订阅者。所有新的未来订户将立即通过此存储的解析值。

以下是一个简单示例,演示您可以在observable完成之前或之后订阅:

const subject = new AsyncSubject();
const o = subject.asObservable();
o.subscribe((v) => {
  console.log(v);
});
interval(500).first().subscribe(subject);

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