随着版本的不停地迭代,新的版本可能会引入一些不兼容的升级(break changes
)。这次遇到的就是forkJoin的用法。
问题的细节
首先,如下代码:
const s1 = api1();
const s2 = api2();
forkJoin([s1, s2]).
.pipe(takeUntil(this._destroyed$))
.subscribe({
});
这时,就能看到如下的Warning (如果使用VSCode的话,forkJoin会被显示为forkJoin ) 。具体的depreciation信息如下:
@deprecated — Pass an array of sources instead. The rest-parameters signature will be removed in v8. Details: https://rxjs.dev/deprecations/array-argument
The signature '(sources_0: ObservableInput<any>): Observable<[any]>' of 'forkJoin' is deprecated.ts(6387)
forkJoin.d.ts(14, 5): The declaration was marked as deprecated here.
官方的Type和Rxjs文档的局限
看看forkJoin的Type定义 (forkJoin.d.ts
):
export declare function forkJoin<T extends AnyCatcher>(arg: T): Observable<unknown>;
export declare function forkJoin(scheduler: null | undefined): Observable<never>;
export declare function forkJoin(sources: readonly []): Observable<never>;
export declare function forkJoin<A extends readonly unknown[]>(sources: readonly [...ObservableInputTuple<A>]): Observable<A>;
export declare function forkJoin<A extends readonly unknown[], R>(sources: readonly [...ObservableInputTuple<A>], resultSelector: (...values: A) => R): Observable<R>;
/** @deprecated Pass an array of sources instead. The rest-parameters signature will be removed in v8. Details: https://rxjs.dev/deprecations/array-argument */
export declare function forkJoin<A extends readonly unknown[]>(...sources: [...ObservableInputTuple<A>]): Observable<A>;
/** @deprecated Pass an array of sources instead. The rest-parameters signature will be removed in v8. Details: https://rxjs.dev/deprecations/array-argument */
export declare function forkJoin<A extends readonly unknown[], R>(...sourcesAndResultSelector: [...ObservableInputTuple<A>, (...values: A) => R]): Observable<R>;
export declare function forkJoin(sourcesObject: {
[K in any]: never;
}): Observable<never>;
export declare function forkJoin<T extends Record<string, ObservableInput<any>>>(sourcesObject: T): Observable<{
[K in keyof T]: ObservedValueOf<T[K]>;
}>;
同时,Rxjs也提供了文章来阐述这种叫做Array Argument的Depreciation信息。详情:Array Arguments
问题是,Rxjs上的文章的hardcode
只能解决用forkJoin处理为数不多的request的情况。如果request的数量位置,那这种hardcode
的方法就不行了。
我的解决方法
下面介绍两种方法。
方法一
使用Array<Observable<any>>
来定义传入参数:
const arreq: Array<Observable<any>> = [];
this.setOfIDs.forEach(id => {
arreq.push(apicall(id));
});
forkJoin(arreq).subscribe({
});
方法二
使用灵活定义的传入参数:
let arreqs: {[index: string]: any} = {};
this.setOfIDs.forEach((id, index)=> {
arreqs[index.toString()] = apicall(id);
});
forkJoin(arreq).subscribe({
});
搞定。