Angular (4): 多个带有Observables的HTTP请求:一个接一个成功
Angular (4): Multiple HTTP requests with Observables: one after another succeeds
我对 Angular 4 和 Observables
以及与之相关的所有内容有点陌生。
我正在尝试一个接一个地执行两个 http
请求(只有 当 第一个请求成功时)。
我正在使用此代码:
public getCompany(id: string): any {
let company = null;
this.authService.isValidUser().subscribe(response => {
const token = this.tokenStorageService.getTokenFromStorage();
const requestUrl = environment.gatewayUrl + environment.companyService + environment.getCompanyEndPoint + id;
const headers = new Headers();
headers.set('Authorization', 'Bearer ' + token);
const options = new RequestOptions({headers: headers});
return this.http.get(requestUrl, options).catch(this.errorService.handleError);
}, (error: AppError) => {
// ........ //
});
}
这是isValidUser()
方法代码:
public isValidUser(): any {
const token = this.tokeStorageService.getTokenFromStorage();
if (!token) {
console.log('cannot find token');
return false;
}
const requestUrl = environment.gatewayUrl + environment.authorizationService + environment.userServiceEndPoint;
const headers = new Headers();
headers.set('Authorization', 'Bearer ' + token);
const options = new RequestOptions({headers: headers});
return this.http.get(requestUrl, options).catch(this.errorService.handleError);
}
这里的想法是 return return this.http.get(requestUrl, options).catch(this.errorService.handleError);
在 authService.isValidUser()
代码生效后。
我认为这不是执行此类请求的正确方式,因为我的第二个请求已经在第一个请求完成之前完成。
也许我缺少一些正确的方法?
谢谢。
您尝试链接这两个函数的代码在哪里?
您可以使用 switchMap
运算符实现您想要的。这是 docs。
我想你需要这样的东西:
isValidUser()
.filter(isValidUser => isValidUser) // <-- perhaps you need this filter since you want to make getCompany call only if user is valid
.switchMap(() => getCompany())
.subscribe(...do something...);
不要忘记添加 import 'rxjs/add/operator/switchMap';
。您也可以使用 mergeMap
或 flatMap
(mergeMap
是 flatMap
的同义词),但这不是首选。
正如@BeetleJuice 在评论中提到的:为什么 switchMap
更好?例如,您使用 mergeMap 或 flatMap 并且某些原因导致了该代码的另一次调用。即使前两个请求没有完成,也会发送新的请求。甚至有可能第二批请求比第一批更快完成。在第一个捆绑包完成后,您的状态中有错误的数据。为了解决这个问题,RxJS 提供了完美的运算符 switchMap
。如果您在上述情况下使用此运算符,则将取消第一个可观察对象(第一个请求包)。只有最后一个可观察到的(来自上次调用的)才会存活。仅当您有可能在短时间内多次 运行 该代码时,您才需要 switchMap。如果您知道此代码只会 运行 一次 mergeMap
/flatMap
将为您做同样的事情。
另外,查看 。
2020 年 3 月 28 日更新:使用新版本的 rxjs,您不能再对返回的 Observable 调用 switchMap 运算符。相反,您需要在 observable 上调用 pipe 并传入之后应该发生的事情。例如:
isValidUser()
.pipe(
switchMap(() => getCompany())
)
.subscribe(...do something...)
也可以将多个运算符传递给管道函数。可以在 operators page
上的 rxjs 网站上找到更多信息
我对 Angular 4 和 Observables
以及与之相关的所有内容有点陌生。
我正在尝试一个接一个地执行两个 http
请求(只有 当 第一个请求成功时)。
我正在使用此代码:
public getCompany(id: string): any {
let company = null;
this.authService.isValidUser().subscribe(response => {
const token = this.tokenStorageService.getTokenFromStorage();
const requestUrl = environment.gatewayUrl + environment.companyService + environment.getCompanyEndPoint + id;
const headers = new Headers();
headers.set('Authorization', 'Bearer ' + token);
const options = new RequestOptions({headers: headers});
return this.http.get(requestUrl, options).catch(this.errorService.handleError);
}, (error: AppError) => {
// ........ //
});
}
这是isValidUser()
方法代码:
public isValidUser(): any {
const token = this.tokeStorageService.getTokenFromStorage();
if (!token) {
console.log('cannot find token');
return false;
}
const requestUrl = environment.gatewayUrl + environment.authorizationService + environment.userServiceEndPoint;
const headers = new Headers();
headers.set('Authorization', 'Bearer ' + token);
const options = new RequestOptions({headers: headers});
return this.http.get(requestUrl, options).catch(this.errorService.handleError);
}
这里的想法是 return return this.http.get(requestUrl, options).catch(this.errorService.handleError);
在 authService.isValidUser()
代码生效后。
我认为这不是执行此类请求的正确方式,因为我的第二个请求已经在第一个请求完成之前完成。
也许我缺少一些正确的方法?
谢谢。
您尝试链接这两个函数的代码在哪里?
您可以使用 switchMap
运算符实现您想要的。这是 docs。
我想你需要这样的东西:
isValidUser()
.filter(isValidUser => isValidUser) // <-- perhaps you need this filter since you want to make getCompany call only if user is valid
.switchMap(() => getCompany())
.subscribe(...do something...);
不要忘记添加 import 'rxjs/add/operator/switchMap';
。您也可以使用 mergeMap
或 flatMap
(mergeMap
是 flatMap
的同义词),但这不是首选。
正如@BeetleJuice 在评论中提到的:为什么 switchMap
更好?例如,您使用 mergeMap 或 flatMap 并且某些原因导致了该代码的另一次调用。即使前两个请求没有完成,也会发送新的请求。甚至有可能第二批请求比第一批更快完成。在第一个捆绑包完成后,您的状态中有错误的数据。为了解决这个问题,RxJS 提供了完美的运算符 switchMap
。如果您在上述情况下使用此运算符,则将取消第一个可观察对象(第一个请求包)。只有最后一个可观察到的(来自上次调用的)才会存活。仅当您有可能在短时间内多次 运行 该代码时,您才需要 switchMap。如果您知道此代码只会 运行 一次 mergeMap
/flatMap
将为您做同样的事情。
另外,查看
2020 年 3 月 28 日更新:使用新版本的 rxjs,您不能再对返回的 Observable 调用 switchMap 运算符。相反,您需要在 observable 上调用 pipe 并传入之后应该发生的事情。例如:
isValidUser()
.pipe(
switchMap(() => getCompany())
)
.subscribe(...do something...)
也可以将多个运算符传递给管道函数。可以在 operators page
上的 rxjs 网站上找到更多信息