我有一个使用登录cookie的应用程序,该cookie与大多数api请求/调用一起发送以验证用户。 (由成功登录后由服务器设置。)
问题是,我的应用程序在启动时同时进行了大量的api调用,导致使用无效会话ID进行的调用,然后为每个调用在服务器端重新创建了会话ID,因此它们最终具有不同的会话ID =>用户注销。
我的计划是在彼此允许之前发送一个api调用。但是不知何故我无法使其按正确的顺序工作。
我想出了一个承诺,它将在我的包装构造函数中的第一个调用完成后得到解决
private firstCallMade: Promise<any>;
constructor(
private http: HttpClient,
private settings: SettingsProvider)
{
this.settings.getAsyncString("apiEndpoint").then(res =>
{
this.apiUrl = res;
this.firstCallMade = new Promise((resolve, reject) =>
{
this.http.get(this.apiUrl + this.firstCallEndpoint, { withCredentials: true })
.subscribe(
(result) => {
this.logger.system(this, 'First Call', `First call successful: ${JSON.stringify(result)}`);
resolve();
},
(error) => {
this.logger.system(this, 'First Call', `First call failed: ${JSON.stringify(error)}`);
resolve();
});
});
});
}
在其他包装方法中,我像这样使用它
get<T>(endpoint: string): Observable<T>
{
return new Observable<T>(subscriber =>
{
this.firstCallMade.then(_ =>
{
this.http.get<T>(this.apiUrl + endpoint)
.subscribe(
next => subscriber.next(next),
error => subscriber.error(error));
});
});
}
但这不起作用。
我的代码错误吗?
编辑说明 所需要的就是全部,但是第一个调用可以同时进行, 完成后(因此为后续调用设置正确的cookie数据)。
答案 0 :(得分:1)
1您不需要forkJoin,需要mergeMap或concatMap,forkJoin通常很差,为什么?因为如果一个请求失败,那么其他一切都会失败。
mergeMap和concatMap,例如,如果十个请求之一失败,则其他九个继续尝试完成。
mergeMap和concatMap之间的区别在于它们执行请求的方式,在mergeMap中,它们是通过“一键式”发送到服务器的,我的意思是,让我们以为您要拉10个日期,mergeMap然后为这10个日期不等待上一个日期完成,而concatMap等待上一个日期完成以向队列添加新请求。
这里有一个示例“如何使用concatMap,mergeMap和forkJoin”:https://angular-bojdob.stackblitz.io
这里是来自Tomas(英语):https://blog.angularindepth.com/practical-rxjs-in-the-wild-requests-with-concatmap-vs-mergemap-vs-forkjoin-11e5b2efe293