添加interceptor后forkJoin并发请求成功回调无法触发问题求助
问题根因排查
- forkJoin 订阅未捕获错误回调
forkJoin 要求所有输入的Observable都**正常完成(complete)**才会触发next回调,只要任意一个Observable抛出错误,就会直接进入error回调。你当前只写了next回调,请求出错时不会有任何日志输出,自然看不到执行。 - 拦截器配置错误引发请求失败
你在请求头里加了Access-Control-Allow-Origin: *,这个是服务端响应头,不能放在客户端请求头中,添加后会触发CORS预检规则,导致请求被浏览器拦截直接报错。 - 无token场景下的逻辑错误
当localStorage中没有token时,你先跳转到登录页,此时发起forkJoin的页面组件会被销毁,订阅自动取消;同时你依然返回next.handle(request)继续发起请求,属于无效逻辑,也可能引发异常。 - 你提供的forkJoin代码存在语法错误
const s0 = return this.http.get <IEntityOne> ('u1');中多了return关键字,属于语法错误,会导致s0不是合法的Observable对象,forkJoin自然无法正常执行。如果是粘贴时的笔误可忽略,否则先修正该语法问题。 - 额外说明:你之前尝试添加的
take(1)是多余操作,Angular HttpClient返回的Observable在请求响应后会自动触发complete,不需要额外手动结束流。
修复方案
- 先给forkJoin的订阅补上error回调,确认是否为请求报错导致的问题:
forkJoin([s0, s1]).subscribe( ([v1, v2]) => { console.log(v1, v2); }, (err) => { console.error('请求失败', err); } )
- 修正拦截器代码:
- 删掉请求头里的
Access-Control-Allow-Origin: '*'配置 - 无token时直接返回空的Observable,不要继续发起请求,避免无效请求和错误
修正后的拦截器代码:
import { EMPTY } from 'rxjs'; intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const token = localStorage.getItem('token'); if (token) { request = request.clone({ setHeaders: { Authorization: `Bearer ${token}` } }); return next.handle(request); } else { this.router.navigate(['/login']); // 无token直接终止请求流,不要继续发送 return EMPTY; } }
- 修正forkJoin的语法错误,去掉多余的return:
const s0 = this.http.get<IEntityOne>('u1'); const s1 = this.http.get<IEntityTwo>('u2');
- 如果问题仍存在,可以给每个请求加
finalize操作符,确认每个请求是否都正常完成:
import { finalize } from 'rxjs/operators'; const s0 = this.http.get<IEntityOne>('u1').pipe(finalize(() => console.log('s0请求结束'))); const s1 = this.http.get<IEntityTwo>('u2').pipe(finalize(() => console.log('s1请求结束')));
只要两个请求都正常完成,forkJoin的next回调一定会触发。
内容的提问来源于stack exchange,提问作者Hello
相关产品推荐
相关产品推荐

