美文网首页
rxjs of操作符生成的Observable对象的执行详细分析

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

作者: 华山令狐冲 | 来源:发表于2021-02-07 09:10 被阅读0次

代码:

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.haomeiwen.com/i2085791/dbef43bb24ab7208.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

所以toSubscriber返回的实际是一个subscriber对象:

![](https://img.haomeiwen.com/i2085791/8d161cd7d9e66890.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://img.haomeiwen.com/i2085791/4122f6334ef217fa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)




首先调用subscriber对象的add方法,目的是通过这个三元表达式,判断到底应该调用subscribe方法,还是trySubscribe方法:

![](https://img.haomeiwen.com/i2085791/8e77892016fb258a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


在我的Angular10,执行后者:

![](https://img.haomeiwen.com/i2085791/fdb95027d64a7591.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


记住这个语义:Observable的subscribe方法,输入参数为subscriber:

![](https://img.haomeiwen.com/i2085791/be8628b90dccc4b7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

_trySubscribe调用_subscribe:

![](https://img.haomeiwen.com/i2085791/2b7698462a68ab0e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

然后就执行到了之前用subscribeToArray返回的function内部:

![](https://img.haomeiwen.com/i2085791/d94b373b8b5f989d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

注意在这个上下文里,我们既有输入,又有应用程序传入的subscribe函数,因此可以调用next了:

![](https://img.haomeiwen.com/i2085791/8e4af67d6e1909a7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://img.haomeiwen.com/i2085791/be4c7aacef44b7a7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)




next和_next的区别就在于有个this.isStopped的判断:

![](https://img.haomeiwen.com/i2085791/0c7c09655091812d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

注意语义:Observable调用subscribe,而subscriber调用next.

![](https://img.haomeiwen.com/i2085791/3cf378403ae1f9bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


subscriber的desination里包含了应用程序传入的callback:

![](https://img.haomeiwen.com/i2085791/094caeed63ffca3a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://img.haomeiwen.com/i2085791/9863a107a713efc5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



subscriber的_tryOrUnsub函数里,最终调用应用程序的callback:

![](https://img.haomeiwen.com/i2085791/75c38ebbcefae508.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![](https://img.haomeiwen.com/i2085791/c7b79315e1c3c377.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

更多Jerry的原创文章,尽在:"汪子熙":
![](https://img.haomeiwen.com/i2085791/7cc33388ba14e967.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

相关文章

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

    代码: 单步调试,首先执行of所在的index.ts: of.js的实现很简单: 没有scheduler,走fro...

  • RxJS源码解读之生成observable的函数

    生成observable的函数 Rxjs中大概提供了32个函数,这些函数执行都返回Observable实例。 用法...

  • Rxjs系列教程目录

    RxJS-中文文档RxJS-中文指南 rxjs学习入门心得(一)Observable可观察对象rxjs学习入门心得...

  • RxJS——Operators

    RxJS 的操作符(operators)是最有用的,尽管 Observable 是最基本的。操作符最基本的部分(p...

  • ☘️RxJs操作符

    RxJS learning RxJS最佳实践 来自官网~ Observable对象可以简化输入提示建议的实现方法,...

  • RxJava操作符学习笔记

    操作符 操作符是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subsc...

  • 看看谁最快的操作符-----Amb

    Amb操作符功能介绍 参数传入多个Observable,哪个Observable中的OnSubscribe执行的快...

  • rxjs-创建类operator

    常用操作符 of 将单个对象转成observable from 将数组转成observable fromEvent...

  • Observable

    快速入门 创建observable 使用observable操作符 可以使用just()或者from()方法将对象...

  • 响应式编程

    响应式编程 可观察对象Angular集成了 参考:Rxjs,它使用 Observable 对象来创建流,主要是用于...

网友评论

      本文标题:rxjs of操作符生成的Observable对象的执行详细分析

      本文链接:https://www.haomeiwen.com/subject/oqhgvktx.html