首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在Angular 7中,为什么HttpClient.post会被执行两次,即使只订阅了一次?

在Angular 7中,HttpClient.post被执行两次的原因可能是由于Angular的Change Detection机制导致的。Change Detection是Angular框架中的一个重要概念,用于检测组件模板中的数据变化并更新视图。

当调用HttpClient.post方法时,它会触发一个异步的HTTP请求,并返回一个Observable对象。在订阅这个Observable对象之前,Angular的Change Detection机制会先执行一次,以检测是否有任何数据变化需要更新视图。这可能会导致HttpClient.post方法被执行一次。

当我们订阅这个Observable对象时,实际上是在告诉Angular我们对这个异步操作感兴趣,并希望在数据返回时执行一些操作。因此,Angular会再次执行一次Change Detection,以确保视图中的数据与最新的数据保持同步。这可能会导致HttpClient.post方法被执行第二次。

为了避免HttpClient.post方法被执行两次,我们可以采取以下几种方法:

  1. 使用take(1)操作符:在订阅Observable对象之前,使用take(1)操作符来确保只订阅一次。这样可以避免多次执行HttpClient.post方法。
代码语言:txt
复制
import { take } from 'rxjs/operators';

httpClient.post(url, data).pipe(take(1)).subscribe(response => {
  // 处理响应数据
});
  1. 使用share()操作符:在订阅Observable对象之前,使用share()操作符来共享Observable的执行结果。这样可以确保多个订阅者共享同一个Observable,避免多次执行HttpClient.post方法。
代码语言:txt
复制
import { share } from 'rxjs/operators';

const observable = httpClient.post(url, data).pipe(share());

observable.subscribe(response => {
  // 处理响应数据
});

observable.subscribe(response => {
  // 处理响应数据
});
  1. 使用async管道:在组件模板中使用async管道来订阅Observable对象,并自动管理订阅和取消订阅的过程。这样可以确保只订阅一次,避免多次执行HttpClient.post方法。
代码语言:txt
复制
<div>{{ (httpClient.post(url, data) | async) }}</div>

以上是解决HttpClient.post被执行两次的几种方法,根据具体情况选择适合的方式。关于Angular的Change Detection机制和HttpClient的更多信息,可以参考腾讯云的Angular开发文档:Angular开发文档

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Angular进阶教程2-

依赖注入与HTTP的介绍 为什么使用服务?...如果你组件中\color{#0abb3c}{组件中}组件中的元数据\color{#0abb3c}{元数据}元数据上定义providers,那么angular会根据providers为这个组件创建一个注入器...,Angular会对延迟加载模块初始化一个新的执行上下文,并创建一个新的注入器,该注入器中注入的依赖该模块内部可见,这算是一个特殊的模块级作用域。...从中我们可以发现observable的一些特性,如下所示: 必须被调用(订阅)才会被执行 observable 被调用后,必须能被关闭,否则会一直运行下去 对于同一个observable,不同的地方subscribe...(observer)都拥有observable的独立执行,上述Observble的介绍也有提及】 Subject的Angular中的常见的作用: 可以Angular通过service来实现不同组件,

4.1K30

理论 | Angular 中的响应式编程 -- 浅淡 Rx 的流式思维

 Rx--隐藏在Angular 2.x中利剑 一文中我们已经初步的了解了 Rx 和 Rx Angular 的应用。 今天我们一起通过一个具体的例子来理解响应式编程设计的思路。...理解 Rx 的关键是要把任何变化想象成数据流,数据流分为几种: 1、永远不会结束的 2、有限次的,比如执行若干次结束的(包括发生一次的) 3、当然还有一些特殊的,比如永远不会发生的(这个是为了解决某些特定场景问题存在的...Async 管道 到目前为止,我们还没有进行对 Observable 的订阅,如果不订阅的话,写的再漂亮的语句也不会执行的。...所幸的是,Angular 提供对于响应式编程非常友好的设计,我们完全可以不在代码中做订阅或取消订阅的动作。那么问题来了,不订阅的话,值怎么获得呢?答案是 Async 管道。...Async 会在组件初始化时自动的订阅以及组件销毁时自动取消订阅,太爽了。

5.3K10
  • 浅谈Hooks&&生命周期(2019-03-12)

    取消订阅Observable并分离事件处理程序以避免内存泄漏。 Angular破坏指令/组件之前 调用。 React生命周期(16.0之前): ? React-Lifecycle1 ?...Hooks React v16.7.0-alpha 中第一次引入了 Hooks 的概念, 为什么要引入这个东西呢?...Counter 这个函数体中,每次 Counter 被渲染的时候,这个 useState 调用都会被执行,useState 自己肯定不是一个纯函数,因为它要区分第一次调用(组件被 mount 时)和后续调用...读者可能会问,现在把 componentDidMount 和 componentDidUpdate 混在一起,那假如某个场景下我 mount 时做事但 update 不做事,用 useEffect...useEffect 还支持第二个可选参数,只有同一 useEffect 的两次调用第二个参数不同时,第一个函数参数才会被调用.

    3.2K40

    详解ANGULAR2组件中的变化检测机制(对比ANGULAR1的脏检测)

    这也是为什么新的变化检测是快速的 (相比于 Angular 1.x 的 $digest)。基本上,每个组件可以几毫秒内执行数万次检测。因此你的应用程序可以快速执行,而无需调整性能。...另外对于单次变化检测,每个组件检查一次。 OnChanges 当组件的任何输入属性发生变化的时候,我们可以通过组件生命周期提供的钩子 ngOnChanges来捕获变化的内容。...虽然 Angular 2 优化后的变化检测执行的速度很快,但我们能否针对那些有变化的组件才执行变化检测或灵活地控制变化检测的时机呢 ? 答案是有的,接下来我们看一下具体怎么进行优化。...也许你已经知道,我们刚才 AppComponent 中模型更新,但视图却未同步更新的原因。...CheckAlways Detached = 3, // 表示该变化检测器树已从根变化检测器树中移除,变化检测将会被跳过 Errored = 4, // 表示执行变化检测时出现异常

    2.9K90

    【响应式编程的思维艺术】 (5)Angular中Rxjs的应用示例

    http请求,Rxjs中通过shareReplay( )操作符将一个可观测对象转换为热Observable(注意:shareReplay( )不是唯一一种可以加热Observable的方法),这样一次订阅时...,网络请求被发出并进行了缓存,之后再有其他订阅者加入时,就会得到之前缓存的数据,运算符的名称已经很清晰,【share-共享】,【replay-重播】,是不是形象又好记。...: sendGet(){ let obs = this.heroService.getHeroes$(); //第一次订阅 obs.subscribe(resp=>{...网络请求发送了一次(之前的会发送两次): ?...Angular中提供一种叫做异步管道的模板语法,可以直接在*ngFor的微语法中使用可观测对象: <li *ngFor="let contact of contacts | async"

    6.7K20

    C#委托和事件

    .NET时代,函数指针有更安全更优雅的包装,就是委托。而事件,则是为了限制委托灵活性引入的新“委托”(之所以为什么限制,后面会谈到)。同样,熟练掌握委托和事件,也是C#登堂入室的标志。...执行过程中,删除两次事件没有报错,但当触发事件时,由于事件订阅列表为空,所以,第二个问题的答案:    多次删除同一事件是不会报错的,即使事件订阅一次。...若出现订阅三次,取消订阅两次时,依旧执行一次。    这个事情是好理解的,事件列表,实际上就是List,最简单的增删问题。 三. 有匿名函数后?...这种情况下,test即使被赋值为null,事件还是会乖乖执行,因为是匿名函数,你也没法取消订阅,而GC强制收集也没用! 这就是我们真实场景中最可怕的事情,你认为它已经消失,可是它还挂在事件上!   ...而且,经过我查阅资料,当你的对象订阅外部的事件,而又没有取消订阅,那么该对象是不会被GC回收的!这会造成很恐怖的问题,产生了几千万个对象没法被回收。可是,匿名函数让我怎么么取消订阅?!

    78520

    Angular核心-组件的生命周期函数钩子函数

    如果组件绑定过输入属性,那么 ngOnInit() 之前以及所绑定的一个或多个输入属性的值发生变化时都会调用。...ngOnInit() 重点 组件初始化完毕等同于Vue.js的mounted 第一轮 ngOnChanges() 完成之后调用,调用一次。...而且即使没有调用过 ngOnChanges(),也仍然会调用 ngOnInit()(比如当模板中没有绑定任何输入属性时)。 ngDoCheck() 组件检查到了系统对自己的影响。...注意:紧跟在每次执行变更检测时的 ngOnChanges() 和 首次执行变更检测时的 ngOnInit() 后调用。 注意:基本用不上。...在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。适合使用在资源释放性语句。 例如:定时器销毁…

    94220

    再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结

    Angular scope 模型上设置一个 监听队列,用来监听数据变化并更新 view 。    ...,进入到 angular context $digest 循环开始执行,查询每个 $watch 是否变化 由于监视 $scope.val 的 $watch 报告了变化,因此强制再执行一次 $digest...这些watchers会检查scope中的当前model值是否和上一次计算得到的model值不同。如果不同,那么对应的回调函数会被执行。...因此,你的function会正常被执行,修改models(如果需要的话),此时一轮$digest循环也会被触发,用来确保view也会被更新。 Note: $scope....$digest 循环不会运行一次。在当前的一次循环结束后,它会再执行一次循环用来检查是否有 models 发生了变化。

    7.8K40

    angular面试题及答案_angular面试

    ngOninit:初始化指令或组件,angular一次显示展示组件的绑定属性后调用,该方法只会调用一次 ngDocheck:检测 ngAfterContentInit:当把内容投影进组件之后调用,...第一次调用ngDocheck()之后调用,调用一次适用于组件 ngAfterContentChecked:每次完成被投影组件内容的变更检测之后调用,适用于组件 ngAfterViewInit...:angular初始化组件及其子组件的视图之后调用,调用一次,适用于组件 ngAfterViewChecked:每次做完组件视图和子视图的变更检测之后调用,适用于组件 ngOnDestroy:...问题就在于请求/响应中消耗大量时间,或者是重新加载使用了大量时间。而在SPA技术中,即使URL不断变化,我们也维护一个页面(index.HTML)。 13....ngOnInit : angular一次显示数据绑定和设置指令、组件的输入属性之后,初始化指令、组件 所以从angular的生命周期看,constructor是执行在先的 所以既然ngOnchanges

    11.1K120

    Angular的12个经典问题,看看你能答对几个?(文末附带Angular测试)

    Angular提供一组生命周期hooks(特殊事件),可以被分接到生命周期中,并在需要时执行操作。构造函数会在所有生命周期事件之前执行。每个接口都有一个前缀为ng的hook方法。...ngOnInit:第一个ngOnChange触发器之后,初始化组件/指令。这是最常用的方法,用于从后端服务检索模板的数据。 ngDoCheck:检测并在Angular上下文发生变化时执行。...每次更改检测运行时,会被调用。 ngOnDestroy:Angular销毁指令/组件之前清除。取消订阅可观察的对象并脱离事件处理程序,以避免内存泄漏。...Angular 2中的路由工作原理是什么? 路由是能够让用户视图/组件之间导航的机制。Angular 2简化了路由,并提供模块级(延迟加载)下配置和定义的灵活性。 ...如果服务器的HTTP请求结果或其它一些异步操作不再需要,则Observable的订阅者可以取消订阅,而Promise将最终调用成功或失败的回调,即使你不需要通知或其提供的结果。

    17.3K80

    把 React 作为 UI 运行时来使用

    如果相同的元素类型同一个地方先后出现两次,React 会重用已有的宿主实例。 这里有一个例子,其中的注释大致解释 React 是如何工作的: ? 同样的启发式方法也适用于子树。...而当我们探讨为什么会这样时却很有意思。 事实上,你很少会直接调用 ReactDOM.render 。相反, React 应用中程序往往会被拆分成这样的函数: ?...同样的,如果你想要解决该问题,你就得 React 之上自己实现细粒度的订阅。 注意,即使细粒度订阅和“反应式”系统也无法解决一些常见的性能问题。...、 React 会将 updater 函数放入队列中,并在之后按顺序执行它们,最终 count 会被设置成 3 并作为一次重渲染的结果。...effect 不只执行一次。当组件第一次展示给用户以及之后的每次更新时它都会被执行 effect 中能触及当前的 props 和 state,例如上文例子中的 count 。

    2.5K40

    24.精读《现代 JavaScript 概览》

    我们可以订阅这些 observables. Hot Observables 容易会被执行, 即使我们没有订阅它们....而cold observable则是需要我们去订阅, 并且会在我们订阅的时候开始执行. 响应式编程 RP 响应式编程, 可以看作是面向异步事件流的编程, 声明式的, 表述去做什么, 而不是怎么做....早在2009年, 双向绑定是 Angualr 最受欢迎的特性之一, 但是 Angular 把这一特性抛弃....JavaScript 运行时, JIT 能够找到代码的特定模式, 而这些模式可以让 JavaScript 更快的被执行....后端渲染的理念很新颖,一定程度帮助 html 认识到自己的不足,就像 Angular, React, Vue 对 webComponents 的冲击一样,或许未来十年可以用上 ECMAScript 标准提供的功能

    54420

    为遗留 Node.js 后端编写自动化测试

    这意味着即使业务逻辑没有改变,有时我们也必须更新我们的自动化测试! 我们的例子中,如果我们决定在测试中模拟 mongodb 依赖,编写和更新测试将需要更多的工作。...这种方式: getHotTracks()调用时可以基于我们的应用程序的执行环境,注入fetchRankedTracks()和fetchCorrespondingPosts()的不同实现:基于 mongodb...认可测试预先收集曲目,实现变更后再次执行检查这些曲目是否保持不变。它们是临时的,直到有可能为我们的业务逻辑编写更好的测试 (例如单元测试) 为止。...我们第一次运行这些测试时,这些测试运行程序将为每个测试断言生成包含传递给 toMatchSnapshot() 的数据的快照文件。...将这些文件提交到我们的版本控制系统 (例如 git) 之前,我们必须检查数据是否正确,是否足以作为参考。因此有这个名字:"认可测试"。

    1.9K30

    Angular(06)- 为什么数据变化,绑定的视图就会自动更新

    这里提一点,前端三大框架(Angular,React,Vue)的数据驱动来更新视图的原理,即 MVVM 的实现。 为什么数据发生变化,绑定的视图就会刷新呢?...vue 要求得声明 data 中的变量,当它变化时才会被追踪到,以更新视图 为什么这些框架会有这些要求,或者说这些规定? 因为它需要知道我们到底什么时刻会去对数据进行更新啊。...那么,当我们直接对变量的赋值操作,其实会去执行 set 的内部逻辑,而 vue 只需要在这里就可以获取我们更新数据的时机。 那么,对于 Angular 呢?...这也是为什么一些 vue 的书中或者项目中,会有要求说某些代码需要放在下一个 tick 中去执行,因为数据源刚发生变化时,页面不一定就更新。...对于 Angular 来说,虽然它是不断轮询的方式来检测数据源是否发生变化,但并不意味着时时刻刻都在轮询检测,而一些有可能导致视图更新的场景下才会去检测。

    1.7K10

    手写防抖函数 debounce 和节流函数 throttle

    防抖:某个函数短时间内执行最后一次。 意思也就是说,函数被触发时,需要先延迟,延迟的时间内,如果再次被触发,则取消之前的延迟,重新开始延迟。这样就能达到,响应最后一次,其余的请求都过滤掉。...这种处理方式有很多实际的应用场景:比如对输入框数据的校验处理,没必要每输入一个字符就校验一遍; 节流:某个函数指定时间段内执行一次,直到指定时间段结束,周而复始。...跟防抖不一样的是,节流是指定时间段内执行一次,也就是这段时间内,只需要响应第一次的请求即可,后续的请求都会被过滤掉,直到下个时间段,重新来过,周而复始。...盗用侵删 这样一来就理解了吧,第一行表示不做任何处理,频繁调用函数,每次都会响应; 经过 debounce 防抖处理后,响应最后一次,因为防抖本质上就是通过延迟,所以实际执行函数时机会晚于函数的请求时机...我们上面举了个 Android 的屏幕刷新机制的例子,也就是一个周期内,可以有无数次会触发屏幕刷新的操作,但其实只要第一次的操作去注册一下帧信号就可以

    3K20

    前端面试题angular_Vue前端面试题

    AngularJSscope变量中使用脏值检查来实现数据双向绑定,并且可以通过scope.watch来监听变化触发回调; angular中使用的是脏检查机制,angular中每次你绑定一些东西到你的...,所以必须进行一次大检查,将所有“注册”过的值全部检查一遍,一次检查称为一个周期,每次最少检查两遍,因为第二遍用来确认,前一遍的变动中是否有数据的变动,导致其他数据的变动,如果第二次有变动的话,会再执行一遍...(至少触发两次 digest 循环) 按下按钮浏览器接收到一个事件,进入到angular context digest 循环开始执行,查询每个 watch 是否变化 由于监视scope.val 的 watch...报告了变化,因此强制再执行一次 digest 循环 新的 digest 循环未检测到变化 浏览器拿回控制器,更新 scope.val 新值对应的 dom 7、一个 angular 应用应当如何良好地分层...貌似 Angular1.x 中并没有很好的解决办法,所以最好在前期进行统一规划,做好约定,严格按照约定开发,每个开发人员写特定区块代码。 9、angular 的缺点有哪些?

    14.1K20
    领券