javascript - 有选择地返回 forkJoin
问题描述
我有一个应用程序应该的情况return menu based on given context
。
以下是 和 的menuA
来源menuB
。
// example of menu derived from given source
menuA() {
return [
{
a: 'demo1',
b: 'demo2',
c: 'demo3'
},
{
e: 'demo4',
f: 'demo5',
g: 'demo6'
}
];
}
// example of menu fetched from different source eg: db
async menuB() {
const ret = [];
const h = {
a: 'demo1',
b: 'demo2',
c: 'demo3'
};
ret.push(h);
return await ret;
}
鉴于我对 的知识和经验有限rxjs
,我希望下面的代码片段可以接受 a ofstring
或menuA
返回menuB
an observable
:required menu
getMenu$(context: string) {
return forkJoin(
{
menuA: of(this.menuA()),
menuB: from(this.menuB())
}
).pipe(
mergeMap((m: any) => {
return m[context];
})
)
}
以上调用警告如下:
Argument of type 'Observable<unknown>' is not assignable to parameter of type 'OperatorFunction<{ menuA: ({ a: string; b: string; c: string; e?: undefined; f?: undefined; g?: undefined; } | { e: string; f: string; g: string; a?: undefined; b?: undefined; c?: undefined; })[]; menuB: { a: string; b: string; c: string; }[]; }, unknown>'.
Type 'Observable<unknown>' provides no match for the signature '(source: Observable<{ menuA: ({ a: string; b: string; c: string; e?: undefined; f?: undefined; g?: undefined; } | { e: string; f: string; g: string; a?: undefined; b?: undefined; c?: undefined; })[]; menuB: { a: string; b: string; c: string; }[]; }>): Observable<...>'.ts(2345)
The 'this' context of type 'void' is not assignable to method's 'this' of type 'Observable<any>'.ts(2684)
根据下面的评论,我还添加了使用 map 替换 mergeMap 时的警告消息:
// modified getMenu$:
getMenu$(context: string) {
return forkJoin(
{
menuA: of(this.menuA()),
menuB: from(this.menuB())
}
).pipe(
map(m => m[context])
)
}
警告信息:
Argument of type 'Observable<unknown>' is not assignable to parameter of type 'OperatorFunction<{ menuA: ({ a: string; b: string; c: string; e?: undefined; f?: undefined; g?: undefined; } | { e: string; f: string; g: string; a?: undefined; b?: undefined; c?: undefined; })[]; menuB: { a: string; b: string; c: string; }[]; }, unknown>'.
Type 'Observable<unknown>' provides no match for the signature '(source: Observable<{ menuA: ({ a: string; b: string; c: string; e?: undefined; f?: undefined; g?: undefined; } | { e: string; f: string; g: string; a?: undefined; b?: undefined; c?: undefined; })[]; menuB: { a: string; b: string; c: string; }[]; }>): Observable<...>'.ts(2345)
The 'this' context of type 'void' is not assignable to method's 'this' of type 'Observable<unknown>'.ts(2684)
我正在使用angular 12
和rxjs "~6.6.0"
。
解决方案
演示:https ://stackblitz.com/edit/typescript-ktm2hz?file=index.ts
function menuA() {
return [
{
a: 'demo1',
b: 'demo2',
c: 'demo3'
},
{
e: 'demo4',
f: 'demo5',
g: 'demo6'
}
];
}
// example of menu fetched from different source eg: db
function menuB() {
return of([
{
a: 'demo1',
b: 'demo2',
c: 'demo3'
}
]).pipe(delay(500));
}
function getMenu$(context: string) {
return forkJoin(of(menuA()), menuB().pipe(first())).pipe(
map(([menuA, menuB]) => ({ menuA, menuB })),
map(m => m[context])
);
}
getMenu$('menuA').subscribe(data => {
console.log(data);
});
getMenu$('menuB').subscribe(data => {
console.log(data);
});
更新:
你需要声明你的菜单。我为它创建了枚举
Angular 12 演示: https ://stackblitz.com/edit/angular-12-template-wcgohi?file=src/app/app.component.ts
import { Component, OnInit } from '@angular/core';
import { forkJoin, Observable, of } from 'rxjs';
import { first, map, delay } from 'rxjs/operators';
enum Menus {
menuA = 'menuA',
menuB = 'menuB'
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
menuA(): { [key: string]: any }[] {
return [
{
a: 'demo1',
b: 'demo2',
c: 'demo3'
},
{
e: 'demo4',
f: 'demo5',
g: 'demo6'
}
];
}
// example of menu fetched from different source eg: db
menuB(): Observable<{ [key: string]: any }[]> {
return of([
{
a: 'demo1',
b: 'demo2',
c: 'demo3'
}
]).pipe(delay(500));
}
getMenu$(context: Menus): Observable<{ [key: string]: any }[]> {
return forkJoin([of(this.menuA()), this.menuB().pipe(first())]).pipe(
map(([menuA, menuB]) => ({ menuA, menuB })),
map(m => m[context])
);
}
ngOnInit() {
this.getMenu$(Menus.menuA).subscribe(data => {
console.log(data);
});
this.getMenu$(Menus.menuB).subscribe(data => {
console.log(data);
});
}
}
推荐阅读
- .net - 我可以将 BlobContainerClient 转换为字符串吗?
- kubernetes - 如何在 ActiveMQ Artemis 中形成具有发现组的 3 个节点的对称集群?
- arrays - C中的数组不保存其值
- redhat - 将 RHV 提供程序添加到 Cloudform 且用户没有特权
- android - 如何以挂起的意图启动 Activity 并清除所有后台堆栈?
- apache-kafka - 如何在kafka流中处理给定时间范围内与键对应的最新记录?
- java - Java Hibernate 项目的文件 root-context.xml 应该放在哪里
- python - 遍历一个 python 字典列表,其中可能包含更多的字典列表等
- vba - MS Access - 记录集 - 循环遍历表并发送电子邮件 - 得到“运行时错误 440:数组索引超出范围
- python - Python不使用sqlite3安装