代码之家  ›  专栏  ›  技术社区  ›  Per Hornshøj-Schierbeck

我如何使用可观察项而不是承诺?

  •  2
  • Per Hornshøj-Schierbeck  · 技术社区  · 8 年前

    我有一个带有一些方法的服务,其中大多数都需要完成某个回调才能完成任务。有了承诺,在pseudo中,很容易做到这一点:

    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 ,也很容易得到更多的东西)。

    承诺会记住它的价值,并知道它是否得到了解决。一个可观察的有点复杂,创建同样的流似乎很麻烦。我需要任何订阅可观察对象的东西,当它准备好时就知道。有时,该方法在可观察物发射之前调用,有时在可观察物发射之后调用。

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

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

    也许我误解了 publishReplay refCount ?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Max Koretskyi    8 年前

    我想你要找的是 AsyncSubject

    AsyncSubject是一个变体,其中只有 可观察执行发送给其观察者,并且仅当 执行完成。

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

    受试者订阅由 first 然后等待,直到完成。它收集所有订阅者,但不向他们发送任何值。一旦底层可观察对象完成,它就会记住该值并将其发送给收集的订阅者。所有未来的新订阅者将立即传递此存储的解析值。

    下面是一个简单的示例,演示了您可以在可观察对象完成之前或之后进行订阅:

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