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

http request within Observable happens even without subscription

我看到 http 请求发生了 - 在 Chrome 网络选项卡中,也通过在获取承诺中使用 then() - 使用以下代码,尽管从未订阅内部可观察对象(saveCourses$).

根据更新的 rxjs 文档,我修改为使用 from() 而不是 fromPromise(),但同样的情况发生了。

我的理解是内部 Observable 不应该 运行?

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'),您将看到一个网络请求。这是问题所在 fromPromise 之前的调用。

虽然基于 Observable 的接口通常会推迟昂贵的工作(如网络调用),直到它们被 订阅,但严格来说这并不是必须的。有时,returns 一个 Observable 的方法甚至在此处的 subscribe method is called. If the Observable does work before its is subscribed, it's often referred to as "hot" (as opposed to "cold" Observables that don't do work unless subscribers are attached). See the "Hot and Cold Observables" 部分之前就已经完成或开始了很多工作。

基于

Promise 的接口工作起来很像 "hot" Observables。也就是说,我们希望一旦调用为我们提供 Promise 的函数,就会开始执行可能代价高昂的操作。当 Promise 被 resolve 时,我们会了解操作的结果,但它会决定我们是否实际监听它(即,将 "then" 处理程序连接到 Promise)。

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

fromPromise(fetch(`/api/courses/${this.course.id}`...)

fromPromise 的工作原理,本质上是等待 Promise 被解析,当它被解析时,通过新创建的 Observable 发出 Promise 的解析值。这里重要的是 fromPromise 必须调用 fetch() 才能获得构建 Observable 的 Promise。而调用fetch的行为会引发网络调用。

所以在这种情况下,但与大多数 "typical" 将 Observables 用于网络或其他长时间操作不同,您不需要调用 .subscribe() 来执行操作。它会在 fetch 被调用时立即执行,并且 fetch 在 Observable 被 created 时调用,而不是在 subscribed[=32= 时调用].