我们在开发复杂的 Angular 应用时,经常会使用到 Rxjs 的 defer 函数,例如:

创建一个 Observable,在订阅时调用 Observable 工厂为每个新的 Observer 创建一个 Observable 对象。

该函数接收一个输入参数,类型为一个工厂函数。输出为一个 Observable 对象,一旦被订阅时,其绑定的工厂函数会被调用。

defer 的实质是延迟创建机制,即只有在返回的 Observable被订阅时,才开始创建 Observable 对象。

defer 允许你只在 Observer 订阅时创建一个 Observable。 它一直等到 Observer 订阅它,调用给定的工厂函数来获取一个 Observable —— 工厂函数通常会生成一个新的 Observable —— 并将 Observer 订阅到这个 Observable。 如果工厂函数返回一个假值,则使用 EMPTY 作为 Observable 代替。 最后但并非最不重要的是,工厂函数调用期间的异常通过调用 error 传递给观察者。

看下面这个具体的例子。

我们来单步调试下上面这段代码。首先进入 defer 内部执行逻辑:

在 defer 内部,直接构造一个新的 Observable,并且将工厂函数传入。该工厂函数在第8行被调用,用于生成一个包含应用程序业务逻辑的 Observable 对象,存储在 input 里。最后,将应用程序的subscriber 订阅到这个工厂函数返回的 Observable 上。

我们再单步执行,发现程序执行流从上图的第5行,跳转到了 第16行。这体现了 defer 函数延迟创建 Observable 对象的行为。所谓延迟创建,准确的说,应该是延迟了包含业务逻辑的 Observable 对象的创建。

紧接着,回到我们的应用代码,此时针对 defer 函数返回的 wrapper Observable 对象调用 subscribe,这时候就会触发包含业务逻辑的 Observable 对象的创建了:

defer 返回的 wrapper Observable 的订阅函数在此处执行:

调用工厂方法,进行包含业务逻辑的 Observable 对象创建:

当前随机数执行结果大于 0.5,返回 fromEvent 生成的新 Observable 对象。

紧接着,第24行的匿名函数 x => console.log(x),每当屏幕被鼠标点击时,就会触发。这个匿名函数本来是订阅到 defer 函数返回的 wrapper Observable 对象的。当工厂函数返回了新的 Observable 对象后,它被自动订阅到这个新的 Observable 对象上。

总结 defer 的工作原理:

(1) defer 函数被调用时,传入一个工厂函数作为输入参数。这个工厂函数返回一个新的包含了业务逻辑的 Observable 对象。

(2) defer 函数返回另一个新的 Observable 对象,这个 Observable 对象称为 wrapper 或者 dummy Observable 对象,因为它不包含任何业务逻辑,存活的唯一价值就是,实现业务逻辑 Observable 对象的延迟创建。

(3) 当 wrapper Observable 被订阅时,触发工厂函数的执行,生成新的 Observable 对象,同时通知其 Observer.

更多Jerry的原创文章,尽在:“汪子熙”:

从一个实际的例子触发,理解什么是 Rxjs 的 defer 函数相关推荐

  1. java c 简单例子_通过一个简单的例子来理解C语言中的LAPACK调用

    我是LAPACK和C / Fortran接口的初学者 . 我需要在Mac OS-X Lion上使用LAPACK / BLAS解决线性方程和特征值问题 . OS-X Lion提供优化的BLAS和LAPA ...

  2. java继承类型转换_#java 一个简单的例子理解java继承、成员函数重写、类型转换...

    一个简单的例子理解java继承.成员函数重写.类型转换 1.继承简介 举一个简单的例子:笔分为很多种,比如毛笔.钢笔.圆珠笔等等,这些笔都有一些相同的属性比如长度.笔迹的粗细等等:但他们也有不同的特点 ...

  3. java 以一个例子来理解面向对象编程思想

    在面向对象的编程中,面向对象的应用是检验你对现实中实际物体和及其关系的抽象能力.在实际编程过程中,你的能力并不是你掌握了多少新的技术,而是对你当前问题的认识的深度,当你理解的足够深的时候,你的框架就出 ...

  4. 一个同行对JAVA的理解

    想来学习Java也有两个年头了,永远不敢说多么精通,但也想谈谈自己的感受,写给软件学院的同仁们,帮助大家在技术的道路上少一点弯路.说得伟大一点是希望大家为软件学院争气,其实最主要的还是大家自身的进步提 ...

  5. 一个简单的例子学会github repository的webhook

    2019独角兽企业重金招聘Python工程师标准>>> github的webhook是个有用的功能,允许开发人员指定一个服务器的url.当开发者对github仓库施加操作,比如提交代 ...

  6. ICLR 2020 | ReClor: 一个需要逻辑推理的阅读理解数据集

    2020-05-12 20:22:59 语言预训练模型在现有流行的阅读理解数据集上取得了惊人的效果,因此,现在是时候引入更复杂的数据集来推动该领域朝着更复杂推理的方向发展了. 新加坡国立大学冯佳时团队 ...

  7. 量子运算 简单通俗例子_什么是量子计算机? 用一个简单的例子解释。

    量子运算 简单通俗例子 by YK Sugi 由YK Sugi 什么是量子计算机? 用一个简单的例子解释. (What is a quantum computer? Explained with a ...

  8. 西门子for循环例子_理解JavaScript中的循环缺陷和迭代协议

    如果您已经用JavaScript或任何语言编程了一段时间,for-循环对你来说不应该陌生.您没有注意到许多编程语言,包括JavaScript,已经从使用for-循环使用迭代器-返回给定集合的下一项的对 ...

  9. React.js 小书 Lesson1-2 - 前端组件化(一):从一个简单的例子讲起

    React.js 小书 Lesson1-2 - 前端组件化(一):从一个简单的例子讲起 本文作者:胡子大哈 本文原文:http://huziketang.com/books/react/lesson2 ...

最新文章

  1. C++在堆区创建数组
  2. nacos 怎么配置 里的配置ip_Nacos-服务注册地址为内网IP的解决办法
  3. [NOTE] XMLHttpRequest
  4. antd4中Form.create已废弃
  5. array.tolist_在Python中使用array.tolist()将数组转换为列表
  6. IDEA快捷键显示重载
  7. .net 代码混淆原理性实践
  8. git 修改已提交的 commit
  9. 阿里达摩院420集python_阿里达摩院推荐的420集的python教程,入门到精通简直不要太简单...
  10. C语言打开微信提示找不到文件,系统弹出提示:windows找不到文件 c:\user\admini~1\temp\appdata\xlliveud。。。什么原因?...
  11. Android基础:ViewPage
  12. Ubuntu下安装SQLite、与简单介绍
  13. 要装系统就装WINDOWSXPSP3VL正式版操作系统
  14. 麒麟v10安装达梦数据库
  15. opencv实现人脸识别和眼部识别
  16. 基于 Python 的时序模型——AMIRA模型
  17. 稠密的方法之一:洗洁精6502透明液态增稠剂
  18. 微信小程序开发入门(二)image标签及图片样式
  19. Loadrunner 报错: Error: The table 'E:\*性能测试脚本\login1\userName.dat' does not exist.
  20. 商汤科技徐立:AI 将在10 年内创造一个印度和中国的总产值

热门文章

  1. oracle 查询数据库io,理解Oracle中的并行查询IO
  2. 详解ScheduledExecutorService的周期性执行方法
  3. 《社交网站界面设计(原书第2版)》——2.11 提问
  4. nginx反向代理缓存服务器构建
  5. openwrt 在centos7 上的开发环境搭建时需要注意的地方
  6. [转载]MVP(SC),MVP(PV),PM,MVVM 和 MVC 表现模式架构对比
  7. mysql5.7.23手动配置安装windows版
  8. 5-4日 socket套接字
  9. request内置对象
  10. MVC 之 属性详解