Observable 在 Angular 中使用 Http 的好处 [英] Benefits of Observable with Http in Angular

查看:87
本文介绍了Observable 在 Angular 中使用 Http 的好处的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

First this answer describes how Observables are helpful in preventing same repeated requests to the server and how we can pause between many requests so that the server doesn't get overloaded.

他们说:

就我在 Angular 中使用 Http 而言,我同意在正常用例中使用 Observable 而不是 Promise 时没有太大区别.在实践中,这里没有任何优势是真正相关的.希望我将来能看到一些高级用例:)

As far as I am using Http in Angular, I agree that in the normal use cases there is not much difference when using Observable over Promise. None of the advantages are really relevant here in practice. Hope I can see some advanced use case in the future :)

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

What I understand here is that when Http is used then Observables benefits are not really relevant.

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

Why is that so? What role is played by Http in this case?
What topic do I have to study to understand Http's role here?

推荐答案

HttpClient 返回的 observable 通常只发出一个值然后完成,表面上看起来很像一个承诺.然而,纯粹为了一致性和/或在 Angular 中总是避免承诺的想法是不正确的.正如其他人所指出的, rel="nofollow nosyncerapplication 一样支持 promise.那么为什么在 http 请求中使用 observables 而不是 promises 呢?因为 observable 提供了另一层抽象.

The observable that HttpClient returns usually only emits one value then completes which, on the surface seems a lot like a promise. However, the idea that it is purely for consistency and/or that promises are always eschewed in Angular isn't true. As others have noted, the async pipe supports promises as does application init. So why use observables instead of promises for http requests? Because observables offer another layer of abstraction.

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

In that thread you linked, this comment makes a crucial point:

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

@gman Exactly. The Promise simply represents some future value. It does not represent the operation which generates the value. You cannot cancel a value. You cannot retry a value. It's just a value. It may or may not be present yet, and it may never exist because an exception occurred, but that's it.

取消

让我们谈谈取消 HTTP 请求.在 observable 的情况下,HttpXhrBackend 只是 HttpBackend通过调用 XMLHttpRequest.abort() 处理取消可观察对象:

Cancellation

Let's talk about cancelling a HTTP request. In the case of the observable, HttpXhrBackend is just one implementation of HttpBackend and handles the cancellation of the observable by calling 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();
  }
};

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

Note that when you're consuming this promise, you don't actually care that it's using XMLHttpRequest and it could be using SomeWhackyAngularXMLHttpRequestThatIsBetter. Let's say we return a promise instead:

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

您的客户怎么能仅凭那个承诺就取消请求?您必须:

How could your client cancel the request with just that promise? You would have to either:

  1. 以某种方式公开实现(在本例中是我们的 XMLHttpRequest 实例).
  2. 围绕XMLHttpRequest(类似于支持中止的httpPromise)提供您自己的抽象层以允许取消.
  1. Somehow expose the implementation (our XMLHttpRequest instance in this case).
  2. Provide your own layer of abstraction around the XMLHttpRequest (something like httpPromise which supports abort) to allow for cancellation.

重复使用

Promise 不可重复使用.假设您想使用 Promise 重试 HTTP 请求.你会怎么做?您猜对了:您必须添加另一个抽象层.在 observables 的情况下,我们有重试支持开箱即用.

结束时值得一提的是,有角度的 HttpClient 并不总是只返回一个值.在您将 reportProgress 设置为 true 的情况下,它会发出多个 HttpEvents ,然后在请求完成时最终完成.有关详细信息,请参阅文档.最后,您应该阅读讨论这个问题的原始问题在 Angular 存储库中一些背景故事.

One thing worth mentioning in closing is that the angular HttpClient doesn't always just return one value. In the case where you set reportProgress to true, it emits multiple HttpEvents before finally completing when the request is complete. See the docs for more info. And finally, you should read the original issue where this was debated in the Angular repo for some backstory.

这篇关于Observable 在 Angular 中使用 Http 的好处的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆