我想进行2个http帖子调用,如果两个调用都失败,则显示错误,如果其中一个调用返回了数据,那么我不想显示该错误。
this.http.post<any[]>(URL, jsonBody1, postJson) //returns an Observable
this.http.post<any[]>(URL, jsonBody2, postJson) //returns an Observable
我可以通过将http帖子变成Promise来做到这一点吗?我尝试了下面的代码,但是没有用。如果第一个then()抛出错误,它将跳过第二个then()并进入catch(),但是如果第一个then()抛出错误,我希望它执行下一个then()。
this.http.post<any[]>(URL, jsonBody1, postJson).toPromise()
.then( data => {
// do something with data
})
.then( _ =>
this.http.post<any[]>(URL, jsonBody2, postJson).toPromise()
.subscribe( data => {
// do something with data
})
)
.catch( error => {
console.log(error);
});
答案 0 :(得分:1)
您可以仅使用Observable
来执行此操作,而不必将其更改为Promise
:
forkJoin(
this.http.post<any[]>(URL, jsonBody1, postJson),
this.http.post<any[]>(URL, jsonBody2, postJson)).subscribe (
x => console.log(x),
error => console.log(error)
() => console.log('completed'))
上述方法可能比使用Promise
更容易。
答案 1 :(得分:0)
您可以使用Promise.all()
Promise.all(
this.http.post<any[]>(URL, jsonBody1, postJson).toPromise(),
this.http.post<any[]>(URL, jsonBody2, postJson).toPromise()
).then(response => {
let [ response1, response2 ] = response
}).catch(err => {
console.log({err})
})
答案 2 :(得分:0)
使用RxJS 6,您可以结合使用forkJoin
,catchError
和map
运算符来实现此目的:
import { forkJoin, of, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
const a$ = of(1);
// const a$ = throwError(new Error('Error in $a'));
// const b$ = of('a');
const b$ = throwError(new Error('Error in $b'));
forkJoin(
a$.pipe(catchError(() => of(null))),
b$.pipe(catchError(() => of(null))),
).pipe(
map(results => {
if (results.some(Boolean)) {
return results;
}
throw new Error(`It's broken.`)
})
)
.subscribe(console.log, console.warn);
观看现场演示:https://stackblitz.com/edit/rxjs6-demo-hgcsnr?file=index.ts
只有两个来源均为false
(捕获错误替换为false
),您才会收到错误消息。
答案 3 :(得分:0)
简单方法
this.http.post<any[]>(URL, jsonBody1, postJson).subscribe(
data => {
this.http.post<any[]>(URL2, jsonBody2, postJson).subscribe(
data2 => {
// both calls succeeded
}
error => {
// set error variable to true
}
)
}
error => {
// set error variable to true
}
)