第三代半导体 ASP.NET iic Netty centos7 人脸识别 vector shiny ftp handlebarsjs Modernizr angularjs版本 vue版本 后台页面模板 建站一条龙 大数据驾驶舱 matlab根号怎么打出来 当前线程等待5秒 bootstrap文件上传样式 ceb转换成pdf在线转换 idea整理代码 字符串中包含某个字符串 flutter项目案例 后台管理网站模板 python字典类型 python环境搭建 python位操作 python自定义异常 java实现接口 java使用mysql java中的对象 java编程学习入门 java开发者 javafloat java怎么使用 java泛型方法 java删除数组中的某个元素 广告代码 js四舍五入 dll文件下载
当前位置: 首页 > 学习教程  > 编程语言

rxjs of操作符生成的Observable对象的执行详细分析

2020/11/4 14:10:04 文章标签:

代码: 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;…

代码:

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)
汪子熙 CSDN认证博客专家 前端框架 Node.js SAP
JerryWang,2007年从电子科技大学计算机专业硕士毕业后加入SAP成都研究院工作至今。Jerry是SAP社区导师,SAP中国技术大使。2020年5月下旬,Jerry做了脑部肿瘤的开颅切除手术,对编程和人生又有了新的感悟。

本文链接: http://www.dtmao.cc/news_show_350097.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?