rxjs of操作符生成的Observable对象的执行详细分析
代码:
const a = of([1, 2, 3]);
a.subscribe((data) => console.log('Fairy:' + data));
单步调试,首先执行of所在的index.ts:
of.js的实现很简单:
import { isScheduler } from '../util/isScheduler';
import { fromArray } from './fromArray';
import { scheduleArray } from '../scheduled/scheduleArray';
export function of(...args) {let scheduler = args[args.length - 1];if (isScheduler(scheduler)) {args.pop();return scheduleArray(args, scheduler);}else {return fromArray(args);}
}
//# sourceMappingURL=of.js.map
没有scheduler,走fromArray这条路:
fromArray.js的实现:
import { Observable } from '../Observable';
import { subscribeToArray } from '../util/subscribeToArray';
import { scheduleArray } from '../scheduled/scheduleArray';
export function fromArray(input, scheduler) {if (!scheduler) {return new Observable(subscribeToArray(input));}else {return scheduleArray(input, scheduler);}
}
//# sourceMappingURL=fromArray.js.map
这个subscribeToArray是一个函数构造器,接收一个数组,返回一个新的函数:
export const subscribeToArray = (array) => (subscriber) => {for (let i = 0, len = array.length; i < len && !subscriber.closed; i++) {subscriber.next(array[i]);}subscriber.complete();
};
//# sourceMappingURL=subscribeToArray.js.map
该函数和我们在应用代码里调用Observable对象的subscribe方法时传入的回调函数有何区别?
继续往下调试。
调用Observable对象的subscribe方法:
ObserverOrNext就是上图第63行的箭头函数,error和complete为undefined:
新建一个Subscriber对象:
subscriber的父类是subscription:
subscriber的destination是一个SafeSubscriber:
SafeSubscriber也是一个Subscriber:
这个emptyObservable啥实现也没有:
import { config } from './config';
import { hostReportError } from './util/hostReportError';
export const empty = {closed: true,next(value) { },error(err) {if (config.useDeprecatedSynchronousErrorHandling) {throw err;}else {hostReportError(err);}},complete() { }
};
//# sourceMappingURL=Observer.js.map
ExtensibilityExtensibility![](https://img-blog.csdnimg.cn/img_convert/fd30a74f127e31a732add12cbcbabc05.png)所以toSubscriber返回的实际是一个subscriber对象:![](https://img-blog.csdnimg.cn/img_convert/d755db210f9042167caa4c3f8e51fbae.png)
![](https://img-blog.csdnimg.cn/img_convert/d7a08902cbd7f7c2cf54a7e8e440be08.png)首先调用subscriber对象的add方法,目的是通过这个三元表达式,判断到底应该调用subscribe方法,还是trySubscribe方法:![](https://img-blog.csdnimg.cn/img_convert/7842df68ea5df9dff9665ee002a0e0bc.png)在我的Angular10,执行后者:![](https://img-blog.csdnimg.cn/img_convert/fc35352eb8125afd3f4cb34c2b936136.png)记住这个语义:Observable的subscribe方法,输入参数为subscriber:![](https://img-blog.csdnimg.cn/img_convert/39930d88fe8b1b7febc9db45584dd876.png)_trySubscribe调用_subscribe:![](https://img-blog.csdnimg.cn/img_convert/c8255b7f4b351bcc80ad7d008b684cf8.png)然后就执行到了之前用subscribeToArray返回的function内部:![](https://img-blog.csdnimg.cn/img_convert/cca17064851f45b8998808a521e16e92.png)注意在这个上下文里,我们既有输入,又有应用程序传入的subscribe函数,因此可以调用next了:![](https://img-blog.csdnimg.cn/img_convert/00b5a512ad77740193ee1d209d188051.png)
![](https://img-blog.csdnimg.cn/img_convert/d6a9930cec4e5d881e6b3a104bda7da3.png)next和_next的区别就在于有个this.isStopped的判断:![](https://img-blog.csdnimg.cn/img_convert/4368c8a5e31f1c595616f2b666383b46.png)注意语义:Observable调用subscribe,而subscriber调用next.![](https://img-blog.csdnimg.cn/img_convert/ed88af507bbecd6b570cdb7dbd887e6f.png)subscriber的desination里包含了应用程序传入的callback:![](https://img-blog.csdnimg.cn/img_convert/831d2d80553d2ee5723196289f8446a5.png)
![](https://img-blog.csdnimg.cn/img_convert/7934c01b71638f69ce2595b6ed3a976f.png)subscriber的_tryOrUnsub函数里,最终调用应用程序的callback:![](https://img-blog.csdnimg.cn/img_convert/4309fcce0db382818f54641af6e04d75.png)
![](https://img-blog.csdnimg.cn/img_convert/f3c9f2197cb9c5812245324c029aee24.png)更多Jerry的原创文章,尽在:"汪子熙":
![](https://img-blog.csdnimg.cn/img_convert/e4a8387dca5921e049fd05f96ef232ae.png)
rxjs of操作符生成的Observable对象的执行详细分析相关推荐
- rxjs of操作符里subscribeToArray的实现原理示意图及分析
写一段简单的代码来测试subscribeToArray: test1(){const subscribeToArray = (array) => (subscriber) => {for ...
- 生成式对抗网络GAN之实现手写字体的生成(基于keras Tensorflow2.0实现)详细分析训练过程和代码
- CGLIB动态代理对象执行流程分析
前言 都说CGLIB动态代理对象执行方法的速度相较于JDK动态代理更快,那么为什么更快,实际是因为CGLIB中采用了FastClass机制,本篇文章将对CGLIB动态代理对象执行某一个方法的流程进行分 ...
- rxjs里的Observable对象和map配合的一个用法
源代码: import { of } from 'rxjs'; import { Injectable } from '@angular/core'; import { map } from 'rxj ...
- rxjs里的Observable对象如何消费
测试代码: import { of } from 'rxjs'; import { Injectable } from '@angular/core';@Injectable() export cla ...
- java hashmap 初始化赋值_HashMap引用传递,对象直接赋值,修改的是同一个对象,new HashMap「」(Map)才是生成新的对象...
HashMap引用传递:对象直接赋值,修改的是同一个对象 MapsrcMap = new HashMap<>(); srcMap.put("a","a&quo ...
- Eclipse自动生成返回值对象与补全与加注释
1.Eclipse自动生成返回值对象,将光标放在;后面按ctrl+1,弹出 Assign statement to new local varible,enter即可. 2.移动代码块快捷键:Alt+ ...
- 从调试器里观察到的Observable对象反推出其赋值的源代码位置
展开Observable对象,从其operator能观察到施加在该Observable对象上的操作: Map操作:(event) => this.getBreakpoint(event.targ ...
- rxjs of操作符传入数组的单步执行
源代码: const a = of([1, 2, 3]);const b = a.pipe(map((data) => {for( let i = 0; i < data.length; ...
最新文章
- 2021年大数据Hadoop(十二):HDFS的API操作
- 【网站汇总】安装教程系列
- ES6深入学习记录(一)class方法相关
- 2021年人工神经网络第一次作业要求
- MATLAB从入门到精通:MATLAB识别 自带手写数字集的CNN(LeNet5)
- Visual Studio 2010 Ultimate开发与测试敏捷特性
- java字符串10_排名前10的Java字符串问题
- Java——String类的方法
- 英文书《用unreal来学习c++》_用机器学习来概括《哈利波特》,四句话总结一场戏...
- 总结各类损失函数【修】
- javascript-流程控制-循环-分支-三元运算符
- Azure站点恢复之----VMM 站点到ASR
- java中什么是字节流和字符流_java中字节流与字符流的区别是什么
- CAD图纸可以约束转换后图纸格式的大小吗?
- 几种码农使用的等宽字体比较——让自己的眼睛爽起来!
- 学学就能进步之LM358介绍
- APISpace 绕口令API接口 免费好用
- 软件测试中单元测试,集成测试,系统测试,验收测试的区别
- C/C++获取系统IP地址
- matlab的subplot--子图位置大小随心所欲