在Angular中使用Http观察的好处

如何解决在Angular中使用Http观察的好处

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

首先,此答案描述了Observables如何有助于防止对服务器的相同重复请求,以及如何在许多请求之间暂停,以免服务器过载。

他们说:

就我在Angular中使用Http而言,我同意在正常使用情况下使用Observable over Promise并没有太大区别。在实践中,这些优势都没有真正相关。希望以后可以看到一些高级用例:)

我在这里了解的是,当使用Http时,Observables的好处并不重要。

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

解决方法

Angular建立在RxJ之上。诸如EventEmitter之类的异步函数是RxJ的可观察形式。 RxJs非常适合异步功能。当Angular构建提供HTTP功能的服务时,开发人员将选择RxJ,从而看到Angular建立在RxJ之上。当我们使用RxJ构建异步应用时,我们不会将其与promise混在一起。

当您只考虑发送请求并获得响应时,似乎并没有多大好处,但是一旦您开始使用RxJ,并了解了它会点击的所有RX运算符。

在学习Angular之前学习RxJ将使您成为更好的Angular开发人员。我希望几年前有人告诉我,因为如果我花一些时间学习RX函数,那么在我还不太完全熟悉RxJ的早期编写的应用程序的编写方式将大不相同。

如果您正在使用Observable,异步管道也是另一个很棒的工具,它也可以与Promise一起使用,但是这意味着您可以直接在模板中使用Observable,而不必管理代码中的订阅。

,

首先,它与一致性有关。混合使用Hex_Grid_Pop <- readOGR(dsn=".",layer="Hex_Grid_500_Pop") df = as.data.frame(Hex_Grid_Pop)[,3:13] df %>% mutate_if(is.numeric,round) Hex_Grid_Pop[1:NROW(Hex_Grid_Pop),3:13] = df head(Hex_Grid_Pop@data) Promise并不是一个好主意,您应该始终记住使用过的内容和使用的地方。

Observable添加了Observable中缺少的一些额外功能。让我们将所有Promises运算符(可帮助您处理数据的内容)排除在本文范围之外。

使用RxJs时要注意三个要点,而不是Observable会带来更多好处:

  • Promise无法执行的重试。
  • 节流和反跳可以在一行中实现。
  • 香草Promise不支持的取消婚姻,
,

首先要提到的是观点。正如您在答案注释中看到的那样,有些人同意而有些人不同意。

我能想到的只有一件事使Http有点特别??。 Http Observable总是很冷。这意味着您只会得到一个结果或一个错误。这使得Http observables有点容易。您可能想调用端点,可能需要稍微修改数据并在屏幕上显示。

Angular中的其他可观察对象(例如Applicative或routerState)很热。这意味着可能会返回多个结果。我可以想象你会用它做更复杂的事情。

,

使http调用成为Observables的一种特殊情况的原因是,http调用可以看作是一个流,该流要么只发出一个值,然后完成,要么出错

可观察的流通常可以发出一个以上的值,可能会或可能不会完成,可能会或可能不会出错。

因此,由于这个原因,即最多发出一个值,http Observables接近Promises,实际上只能发出一个值或错误。

尽管如此,在现实生活中将Observables用于HTTP调用还是有优势的,特别是当您必须将多个http调用与其他异步事件流组合在一起时。在this article中,有一些典型的将Observables与http调用结合使用的模式,您可以在其中欣赏rxjs运算符的好处。

,

HttpClient返回的可观察值通常仅发出一个值然后完成,表面上看起来很像一个承诺。但是,纯粹出于一致性和/或始终在Angular中避免承诺的想法是不正确的。正如其他人指出的,async pipeapplication init一样都支持诺言。那么,为什么要对HTTP请求使用observables而不是promise?因为可观察对象提供了另一层抽象。

在您链接的那个线程中,this comment提出了一个关键点:

@gman确实如此。无极承诺只是代表一些未来价值。它不代表生成值的操作。您无法取消值。您无法重试值。这只是一个价值。它可能存在或可能不存在,并且可能永远不存在,因为发生了异常,仅此而已。

取消

让我们谈谈取消HTTP请求。对于可观察的情况,通过调用HttpXhrBackendHttpBackend只是XMLHttpRequest.abort()handles the cancellation of the observable的一种实现:

// 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。假设我们改为返回承诺:

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

您的客户如何仅凭那个承诺就可以取消请求?您将必须:

  1. 以某种方式公开实现(在这种情况下,我们的XMLHttpRequest实例)。
  2. XMLHttpRequest(类似于httpPromise,支持中止)周围提供您的 own 抽象层,以供取消。

重复使用

承诺不可重用。假设您要使用Promise重试HTTP请求。你会怎么做?您猜对了:您将不得不添加另一层抽象。对于可观察物,我们提供了retry support

结论

结束语中值得一提的是,角度HttpClient并不总是返回一个值。在将reportProgress设置为true的情况下,它会在请求完成后最终完成之前发出多个HttpEvents。有关更多信息,请参见the docs。最后,您应该阅读Angular仓库中的the original issue where this was debated以获得一些背景知识。

,

我认为关键的区别在于Observables如何能够取消订阅。承诺依赖于解决或拒绝。 使用Observables还有很多其他的优点,我主要倾向于Angular。这是一个理想国。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-