为什么当我将其转换为 Promise 时,我的自定义可观察行为会有所不同?

Why my custom observable behaviour is different when i transform it to Promise?

我有以下观察结果

  callOne() {
    return new Observable(subscriber => {
      subscriber.next(true);
      setTimeout(() => {
        subscriber.complete();
      }, 3000)
    })
  }

  callTwo() {
    return new Observable(subscriber => {
      subscriber.next(false);
      setTimeout(() => {
        subscriber.complete();
      }, 1000)
    })
  }

所以当我打电话订阅他们时


 this.callOne().subscribe(data => {
      console.log(data);
    })

    this.callTwo().subscribe(data => {
      console.log(data);
    })

我立即打印真假,即使我在 setTimeout 中设置了完整的方法。 我是说在 x miliseconds 中执行 complete 方法后无法发出新值。

当我尝试相同但这次 observables 被转换为 promises


 let response1 = await this.callOne().toPromise();
    console.log('response1', response1);
    let response2 = await this.callTwo().toPromise();
    console.log('response2', response2);

然后我在 3000 毫秒内从可观察到的 callOne 打印出 true。 这是为什么?

为什么当我承诺完整的方法会被 setTimeout 考虑在内 但对于 observable 它不是 ?

您应该更改代码中的某些内容。您必须 运行 setTimout 中的下一个方法。因为当你 运行 下一个方法 observables 被触发并且你订阅了一个 observable 它将调用。

callOne() {
  return new Observable(subscriber => {

    setTimeout(() => {
      subscriber.next(true); // you can use like this
      subscriber.complete(); 
    }, 6000)
  })
}

但是,当您使用 await 时,它的工作方式与 then() 类似,并且当一切都完成时它会调用 complete。

Observable 和 promises 是不同的东西,尽管它们可能会将一个转化为另一个。

你所面对的是意料之中的。 promise 在 observable 完成之前不会“解决”,因此只有在完成后它才会 运行 逻辑,这就是 promises 的工作方式。 Observable 在这个意义上是不同的。

事实上,如果您没有完成流,在订阅中您仍然会得到代码 运行,但在流永远不会完成的承诺中,它不会 运行 任何东西.一个非常常见的错误是将 long-life 热可观察对象转换为 promise。

我想承诺在 subscriber.complete() 调用之前不会解决。由于您使用了 await,执行将不会继续,直到承诺解决。

这篇文章实际上解释了从toPromise()返回的promise等待observable完成,然后returns最后一个值:https://levelup.gitconnected.com/rxjs-operator-topromise-waits-for-your-observable-to-complete-e7a002f5dccb

toPromise() 虽然已被弃用,所以我不会费心使用它。您可以将 Observables 包装在 Promises 中。然后您可以准确控制它们何时解决。

  callOne() {
    const observable = new Observable((subscriber) => {
      subscriber.next(true);
      setTimeout(() => {
        subscriber.complete();
      }, 3000);
    });
    return new Promise((resolve) => {
      observable.subscribe((result) => resolve(result));
    });
  }

这个承诺将在 subscriber.next() 的第一次调用时解决,我相信这正是您所期望的。

请记住,Observables 可以重复调用 .next(),但 Promises 只能解析一次。