在 Angular 中使用 Http 进行 Observable 的好处

Aqu*_*irl 8 http observable rxjs angular-promise angular

从这里:https ://stackoverflow.com/a/40135509/462608

首先,这个答案描述了 Observables 如何有助于防止向服务器发出相同的重复请求,以及我们如何在多个请求之间暂停,以便服务器不会过载。

他们说:

就我在 Angular 中使用 Http 而言,我同意在正常用例中使用 Observable 与 Promise 没有太大区别。这些优点在实践中都没有真正相关。希望我将来能看到一些高级用例:)

我在这里理解的是,当使用 Http 时,Observables 的好处并不真正相关。

为什么会这样?Http在这种情况下扮演什么角色呢?
我必须研究什么主题才能理解 Http 在这里的作用?

Dea*_*ean 6

返回的 observableHttpClient通常只发出一个值,然后完成,从表面上看,这很像一个承诺。然而,认为这纯粹是为了一致性和/或在 Angular 中总是回避 Promise 的想法并不正确。正如其他人所指出的,异步管道与application init一样支持 Promise 。那么为什么要使用 observables 而不是 http 请求的 Promise 呢?因为可观察量提供了另一层抽象。

在您链接的线程中,此评论提出了一个关键点:

@gman 没错。Promise 只是代表一些未来的价值。它并不代表生成该值的操作。您无法取消某个值。您无法重试某个值。这只是一个值。它可能存在,也可能不存在,也可能因为发生异常而永远不存在,但仅此而已。

消除

我们来谈谈取消 HTTP 请求。对于可观察的情况,HttpXhrBackend只是一种实现HttpBackend,并通过调用来处理可观察的取消XMLHttpRequest.abort()

// This is the return from the Observable function, which is the
// request cancellation handler.
return () => {
  // On a cancellation, remove all registered event listeners.
  xhr.removeEventListener('error', onError);
  xhr.removeEventListener('load', onLoad);
  if (req.reportProgress) {
    xhr.removeEventListener('progress', onDownProgress);
    if (reqBody !== null && xhr.upload) {
      xhr.upload.removeEventListener('progress', onUpProgress);
    }
  }

  // Finally, abort the in-flight request.
  if (xhr.readyState !== xhr.DONE) {
    xhr.abort();
  }
};
Run Code Online (Sandbox Code Playgroud)

请注意,当您使用此承诺时,您实际上并不关心它正在使用XMLHttpRequest并且它可能正在使用SomeWhackyAngularXMLHttpRequestThatIsBetter. 假设我们返回一个承诺:

// How would something that consumes this call xhr.abort()?
function myHttpGetPromise(method, url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.onload = resolve;
        xhr.onerror = reject;
        xhr.send();
    });
}
Run Code Online (Sandbox Code Playgroud)

您的客户怎么可能仅仅凭着这样的承诺就取消请求呢?你必须:

  1. 以某种方式公开实现(XMLHttpRequest本例中是我们的实例)。
  2. 围绕(类似支持中止的东西)提供您自己的抽象层以允许取消。XMLHttpRequesthttpPromise

重复使用

Promise 不可重复使用。假设您想使用 Promise 重试 HTTP 请求。你会怎么做?您猜对了:您必须添加另一层抽象。对于可观察量,我们提供开箱即用的重试支持。

结论

最后值得一提的是,角度HttpClient并不总是只返回一个值。在设置为 true 的情况下,当请求完成时reportProgress,它会在最终完成之前发出多个。HttpEvents请参阅文档以获取更多信息。最后,您应该阅读Angular 存储库中对此进行辩论的原始问题,了解一些背景故事。