TypeScript 将 Observable<Student[]>[] 转换为 Observable<Student[]>
TypeScript Convert Observable<Student[]>[] to Observable<Student[]>
我正在尝试处理学生集合,并且对于每个学生调用不同的服务器 api,我如何合并来自不同 api 的响应?
这里是问题的演示代码:
test4(students:Student[]):Observable<Student[]> {
var rr = students.map(student =>{
if (student.age === 1) {
return this.client
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.pipe(
map((res) => {
console.log(res);
student.age = student.age * 100;
return [student];
})
);
} else {
return this.client
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.pipe(
map((res) => {
console.log(res);
student.age = student.age * 10000;
return [student];
})
);
}
});
}
如果可能的话,我不想使用forkjoin。
更新
我有这样的源数据
getStudents(): Student[] {
return [{ age: 1 }, { age: 2 }, { age: 3 }];
}
如果年龄=1,则return1100;如果年龄 >1 则 return 110000;在 *100 或 *10000 之前,它会向不同的 api 发送请求,我在上述代码中模拟了 http 请求
函数的输入和输出将为 test4(students: Student[]): Observable<Student[]>
,这意味着最终结果将类似于 of([{ age: 100 }, { age: 20000 }, { age: 30000 }])
。
我还有另一个调用 test4
的函数,如下所示:
test() {
this.test4(this.getStudents())
.pipe(
mergeMap((result) => {
console.log(result);
return of([]);
})
)
.subscribe();
}
它会记录类似 [{ age: 100 }, { age: 20000 }, { age: 30000 }]
的内容
这是一种可能的解决方案,使用 from
将数组转换为可观察流。 concatMap
将依次执行 api,最后 toArray()
会将所有输出分组到一个数组中。
import './style.css';
import { of, map, from } from 'rxjs';
import { concatMap, toArray } from 'rxjs/operators';
from([{ age: 1 }, { age: 4 }])
.pipe(
concatMap((student) => {
return from(
fetch('https://api.coindesk.com/v1/bpi/currentprice.json').then((res) =>
res.json()
)
).pipe(
map((res) => {
console.log(res);
student.age = student.age * (student.age === 1 ? 100 : 10000);
return student;
})
);
}),
toArray(),
)
.subscribe((output) => console.log(output));
输出:
[Object, Object]
0: Object
age: 100
__proto__: Object
1: Object
age: 40000
__proto__: Object
根据最新输入,您需要使用 of
运算符修改结果和 return 以获得可观察值。
getStudents(): Student[] {
return [{ age: 1 }, { age: 2 }, { age: 3 }];
}
test4(inputArray: Array<Student>): Observable<Student[]> {
return of(inputArray.map((student) => {
student.age = student.age * (student.age === 1 ? 100 : 10000);
return student;
})
}
test() {
this.test4(this.getStudents())
.pipe(
mergeMap((result) => {
console.log(result);
return of([]);
})
)
.subscribe();
}
我正在尝试处理学生集合,并且对于每个学生调用不同的服务器 api,我如何合并来自不同 api 的响应?
这里是问题的演示代码:
test4(students:Student[]):Observable<Student[]> {
var rr = students.map(student =>{
if (student.age === 1) {
return this.client
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.pipe(
map((res) => {
console.log(res);
student.age = student.age * 100;
return [student];
})
);
} else {
return this.client
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.pipe(
map((res) => {
console.log(res);
student.age = student.age * 10000;
return [student];
})
);
}
});
}
如果可能的话,我不想使用forkjoin。
更新
我有这样的源数据
getStudents(): Student[] {
return [{ age: 1 }, { age: 2 }, { age: 3 }];
}
如果年龄=1,则return1100;如果年龄 >1 则 return 110000;在 *100 或 *10000 之前,它会向不同的 api 发送请求,我在上述代码中模拟了 http 请求
函数的输入和输出将为 test4(students: Student[]): Observable<Student[]>
,这意味着最终结果将类似于 of([{ age: 100 }, { age: 20000 }, { age: 30000 }])
。
我还有另一个调用 test4
的函数,如下所示:
test() {
this.test4(this.getStudents())
.pipe(
mergeMap((result) => {
console.log(result);
return of([]);
})
)
.subscribe();
}
它会记录类似 [{ age: 100 }, { age: 20000 }, { age: 30000 }]
这是一种可能的解决方案,使用 from
将数组转换为可观察流。 concatMap
将依次执行 api,最后 toArray()
会将所有输出分组到一个数组中。
import './style.css';
import { of, map, from } from 'rxjs';
import { concatMap, toArray } from 'rxjs/operators';
from([{ age: 1 }, { age: 4 }])
.pipe(
concatMap((student) => {
return from(
fetch('https://api.coindesk.com/v1/bpi/currentprice.json').then((res) =>
res.json()
)
).pipe(
map((res) => {
console.log(res);
student.age = student.age * (student.age === 1 ? 100 : 10000);
return student;
})
);
}),
toArray(),
)
.subscribe((output) => console.log(output));
输出:
[Object, Object]
0: Object
age: 100
__proto__: Object
1: Object
age: 40000
__proto__: Object
根据最新输入,您需要使用 of
运算符修改结果和 return 以获得可观察值。
getStudents(): Student[] {
return [{ age: 1 }, { age: 2 }, { age: 3 }];
}
test4(inputArray: Array<Student>): Observable<Student[]> {
return of(inputArray.map((student) => {
student.age = student.age * (student.age === 1 ? 100 : 10000);
return student;
})
}
test() {
this.test4(this.getStudents())
.pipe(
mergeMap((result) => {
console.log(result);
return of([]);
})
)
.subscribe();
}