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

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


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

在我的Angular10,执行后者:

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

_trySubscribe调用_subscribe:

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

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


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

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

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


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


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

网友评论