我有一个进行两次http调用的函数,第二个http的输入取决于第一个http响应,我需要同时返回两个结果。我有以下代码抛出错误
SomeMethod(): Observable<any> {
let firstResult;
let secondResult;
firstResult = http.get('////').map(data => {
console.log('first response')
secondResult = http.get('//// + {data.UserId}').map(response => {
console.log('second response')
})
})
return forkJoin([firstResult, secondResult]);
}
CallingMethod() {
this.SomeMethod.subscribe(([firstResult, secondResult]) =>{
/// Some logic
})}
将错误视为未定义。期望一个可观察的、承诺的或数组。调试后知道第一个控制台输出正在打印,第二个 http 调用永远不会进行,也永远不会看到响应。
如何使用forkJoin或任何其他机制一起返回两个嵌套的调用响应?
这是一个如何使用concatMap
执行此操作的 StackBlitz 。concatMap
将按顺序执行,而 asforkJoin
将并行执行。
您需要了解的内容
const requests = [
this.http.get('https://jsonplaceholder.typicode.com/todos/1'),
this.http.get('https://jsonplaceholder.typicode.com/todos/2'),
this.http.get('https://jsonplaceholder.typicode.com/todos/3'),
this.http.get('https://jsonplaceholder.typicode.com/todos/4'),
this.http.get('https://jsonplaceholder.typicode.com/todos/5'),
this.http.get('https://jsonplaceholder.typicode.com/todos/6')
];
from(requests).pipe(
concatMap((request) => request.pipe(delay(2200)))
).subscribe((res) => {
this.results$.next(this.results$.getValue().concat(res))
})
- 我们创建一个请求数组(这是可观察的(。
- 使用
from
运算符获取数组并发出每个数组项 - 用
concatMap
平息这些排放
我还在此处添加了延迟以模拟缓慢加载。
使用 Async & await 来控制多个 http 请求。
async SomeMethod(): Promise <any> {
let firstResult;
let secondResult;
firstResult = await http.get('////').toPromise();
secondResult = await http.get('//// + {res1.UserId}').toPromise();
return forkJoin(firstResult, secondResult);
}
CallingMethod() {
this.SomeMethod().then(result => {
/// Some logic
});
}
以下代码应该有效:
SomeMethod(): Observable < any > {
let firstResult;
let secondResult;
return http.get('////').pipe(
switchMap(res1 => http.get('//// + {res1.UserId}').pipe(
map(res2 => [res1, res2])
))
);
}
CallingMethod() {
this.SomeMethod().subscribe(([firstResult, secondResult]) => {
/// Some logic
})
}
forkJoin
内联参数,而不是数组(除非这是 rxjs 在最新和 Angular v4 中捆绑的内容之间的变化(
const req1 = this.http.get('https://jsonplaceholder.typicode.com/todos/1');
const req2 = this.http.get('https://jsonplaceholder.typicode.com/todos/2');
const results = forkJoin(req1, req2)
输出:
[
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
}
]
StackBlitz在v6中,但如果需要,它很容易回溯。