目录:
- 一.raw Observable's subscrbe
- 二.piped Observable's subscrbe?
正文:
一.raw Observable's subscrbe
我们把of,from,interval这些没有经过操作符处理的Observable成为raw Observable,它的subscribe()是最简单的被订阅
const nextObsever = i => console.log(i);
of(1).subscribe(nextObsever);
// output: 1
这里被订阅指的是nextObsever作为订阅者,of(1)作为发布者,of()在内部调用了fromArray(),它定义在rxjs/src/internal/observable/fromArray.ts:
export function fromArray<T>(input: ArrayLike<T>, scheduler?: SchedulerLike) {
if (!scheduler) {
return new Observable<T>(subscribeToArray(input));
} else {
return scheduleArray(input, scheduler);
}
}
从上面我们可以看到:
-
raw Observable通常还可以接收第二个参数,它是一种scheduler,用来控制发布者发布的时机,就像js里面的setTimeout, setInterval之类的 -
subscribeToArray()接收of()的入参作为自己的入参,并返回一个函数,它定义在rxjs/src/internal/util/subscribeToArray.ts:export const subscribeToArray = <T>(array: ArrayLike<T>) => (subscriber: Subscriber<T>) => { for (let i = 0, len = array.length; i < len && !subscriber.closed; i++) { subscriber.next(array[i]); } subscriber.complete(); };返回的函数(暂且称作
rt)将接收一个subscriber对象,然后将of()的入参通过该对象的next接口传递给subscriber,这个Subscriber实际上是Observer的增强版,定义在rxjs/src/internal/Subscriber.ts:export class Subscriber<T> extends Subscription implements Observer<T> { -
Subscriber不像Observer那样对外开放标准,它是在内部用来处理subscribe这个方法的参数,我们都知道subscribe方法接收两种形式的传参:// 1. of(1).subscribe( () => {}, // next () => {}, // error () => {} // complete ); // 2. of(1).subscribe({ next() { }, error() { }, complete() { } });如果是第二种传参,
rt函数直接接收一个obsever就行了,但是对第一种传参就不行了,所以subscriber是对两种传参进行了处理之后的对象,它将第一种参数转换成了第二种参数的形式 -
具体的转换过程发生在
subscribe()执行的时候:subscribe(observerOrNext?: PartialObserver<T> | ((value: T) => void), error?: (error: any) => void, complete?: () => void): Subscription { const { operator } = this; const sink = toSubscriber(observerOrNext, error, complete); if (operator) { sink.add(operator.call(sink, this.source)); } else { sink.add( this.source || (config.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? this._subscribe(sink) : this._trySubscribe(sink) ); } if (config.useDeprecatedSynchronousErrorHandling) { if (sink.syncErrorThrowable) { sink.syncErrorThrowable = false; if (sink.syncErrorThrown) { throw sink.syncErrorValue; } } } return sink; }可以看到传入的
observerOrNext有两种可能,toSubscriber实现了整个转化统一的过程,为了不丢失主线,转化的过程在这里就不详细讲了。现在
sink已经是一个subscriber了,它的next方法指向我们传入的observerOrNext,此时我们只需要把sink传入rt,就可以完成整个消息传递的过程 -
raw Observable是没有operator的,所以上面实际执行了this._subscribe(sink),这个this._subscribe在我们实例化Observable的时候指向了rt:constructor(subscribe?: (this: Observable<T>, subscriber: Subscriber<T>) => TeardownLogic) { if (subscribe) { this._subscribe = subscribe; } }这里要注意,
Observable自己定义了默认的__subscribe(),如果我们调用subscribe(nextFn)时传了nextFn,则它会覆盖默认的__subscribe()。至此整个消息传递的过程的就完成了,但这只是
rxjs里面最简单的被订阅,了解它的基本原理之后,接下来去理解操作符的被订阅就很easy了
二.piped Observable's subscrbe?
未完待续...