Javascript 即使没有订阅,Observable中的http请求也会发生

Javascript 即使没有订阅,Observable中的http请求也会发生,javascript,angular,ecmascript-6,rxjs6,Javascript,Angular,Ecmascript 6,Rxjs6,我看到http请求发生在Chrome网络选项卡中,也通过在fetch promise中使用then(),使用下面的代码,尽管从未订阅内部可观察(saveCourses$) 根据更新的rxjs文档,我修改为使用from(),而不是fromPromise(),但情况也一样 我的理解是,内在的可观察不应该运行 ngOnInit() { this.form.valueChanges.pipe( filter(() => this.form.valid) ) .subscri

我看到http请求发生在Chrome网络选项卡中,也通过在fetch promise中使用
then()
,使用下面的代码,尽管从未订阅内部可观察(
saveCourses$

根据更新的rxjs文档,我修改为使用
from()
,而不是
fromPromise()
,但情况也一样

我的理解是,内在的可观察不应该运行

ngOnInit() {
  this.form.valueChanges.pipe(
    filter(() => this.form.valid)
  )
    .subscribe(changes => {
      const saveCourses$ = fromPromise(fetch(`/api/courses/${this.course.id}`, {
        method: 'PUT',
        body: JSON.stringify(changes),
        headers: {
          'content-type': 'application/json'
        }
      }));
    });
}

停止使用
fetch
并使用
HttpClient
。如果打开控制台并键入
fetch('foo')
,您将看到一个网络请求。这就是问题所在。

基于可观察的接口通常会将昂贵的工作(如网络调用)推迟到订阅之前,但严格来说这并不一定。有时,返回可观察对象的方法甚至在调用其方法之前就已经完成或开始了大量工作。如果可观测对象在订阅之前就工作了,它通常被称为“热”可观测对象(与“冷”可观测对象相反,除非附加订阅对象,否则不工作)。请看这里的部分

-基于接口的工作方式非常类似于“热”观测。也就是说,我们希望,一旦调用给我们承诺的函数,潜在的昂贵操作就会启动。当承诺得到解决时,我们会了解操作的结果,但它会解决我们是否真正听取了它(即,将一个“then”处理程序连接到承诺)

在您的示例中,您的Observable是使用
fromPromise
方法创建的:

fromPromise(fetch(`/api/courses/${this.course.id}`...)
从本质上讲,fromPromise的工作原理是,等待一个承诺被解决,当它被解决时,通过一个新创建的可观察对象发出承诺的解决值。这里重要的一点是,
fromPromise
必须调用fetch(),以获得构建可观察对象的承诺。调用fetch的行为导致网络调用被启动


因此,在本例中,与网络或其他长操作中观察对象的大多数“典型”用法不同,您不需要调用.subscribe()来执行操作。调用
fetch
后,它将立即执行,并且在创建可观察对象时调用
fetch
,而不是在订阅时。

fromPromise方法很可能立即使用promise将其转换为可观察对象。你为什么不使用内置的Angular http工具来完成你想要的事情呢?我正在学习Angular大学的rxjs课程-我不打算在任何项目中使用fetch,但对于这个例子,我理解没有订阅就不应该发生http请求(根据尚未回到我身边的课程作者)。我真的很想理解为什么会发生这种自动订阅。据说,它发生在
fromPromise
代码中。传递到
可观察的
代码中的回调立即调用
then
方法。我正在上rxjs的Angular大学课程-我不打算在任何项目中使用fetch,但是对于这个例子,我理解如果没有订阅,http请求不应该发生(根据课程作者的说法,他还没有回来找我)。我真的很想理解为什么会发生这种自动订阅。感谢您提供清晰详细的解释。还有一个要点-我创建了一个函数,该函数在Observable.create()中调用fetch方法,在这种情况下不会触发http请求,除非我明确订阅-因此这意味着特别是fromPromise和fetch的组合导致了原始问题中的问题,而不仅仅是使用fetch,对吗?@DJC对,区别在于传递给
Observable.crea的函数te
仅在订阅可观察对象时调用。与创建可观察对象时调用提供的函数的
fromPromise
的行为相比,这是一个比较好的选择。非常感谢您的详细解释。事实证明,您弄错了;)