美文网首页
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对象的执行详细分析

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