Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度HttpClient可观察到未完成_Javascript_Angular_Rxjs_Observable_Angular Httpclient - Fatal编程技术网

Javascript 角度HttpClient可观察到未完成

Javascript 角度HttpClient可观察到未完成,javascript,angular,rxjs,observable,angular-httpclient,Javascript,Angular,Rxjs,Observable,Angular Httpclient,我有以下代码: // in a service downloadCSV(): Observable<Blob> { return this.httpClient.get(`${apiUrl}/a.csv`, {responseType: 'blob'}); } // in component onDownloadClicked(event: MouseEvent) { this.downloading = true; this.service.downloadCSV()

我有以下代码:

// in a service
downloadCSV(): Observable<Blob> {
  return this.httpClient.get(`${apiUrl}/a.csv`, {responseType: 'blob'});
}
// in component
onDownloadClicked(event: MouseEvent) {
  this.downloading = true;
  this.service.downloadCSV()
    .pipe(finalize(() => this.downloading = false))
    .subscribe(
      (data: Blob) => {
        console.log(data);
      },
      (error) => {
        console.error(error);
        alert('Sorry, something wet wrong. Try again.');
      },
      () => {
        console.log('completed!');
      }
    );
}
//在服务中
downloadCSV():可观察{
返回这个.httpClient.get(`${apirl}/a.csv`,{responseType:'blob'});
}
//组件中
onDownloadClicked(事件:MouseeEvent){
this.downloading=true;
this.service.downloadCSV()
.pipe(finalize(()=>this.downloading=false))
.订阅(
(数据:Blob)=>{
控制台日志(数据);
},
(错误)=>{
控制台错误(error);
警报('抱歉,有问题。请重试');
},
() => {
console.log('completed!');
}
);
}
数据记录正确,但“已完成!”不会记录,也不会调用finalize

编辑:

因此,在进一步的调查中,问题似乎与添加auth头的拦截器有关

如果拦截器被绕过(并且在服务器上禁用了身份验证),则可观察对象将无误地完成

我不明白为什么会这样。可能与请求被克隆的事实有关

//interceptor code
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  let scope: string;
  // only inject tokens for the following scopes
  if (req.url.indexOf('https://graph.microsoft.com') === 0) {
    scope = 'https://graph.microsoft.com';
  }
  else if (req.url.indexOf('https://management.azure.com') === 0) {
    scope = 'https://management.azure.com';
  }
  else if (req.url.indexOf(environment.apiUrl) === 0) {
    scope = environment.appId;
  }
  if (scope) {
    return this.authService.getToken(scope).pipe(
      switchMap((token) => {
        let newReq;
        if (token) {
          const JWT = `Bearer ${token}`;
          newReq = req.clone({
            setHeaders: {
              Authorization: JWT,
            }
          });
        }
        return next.handle(newReq || req);
      })
    );
  }
  else {
    return next.handle(req);
  }
}
//拦截器代码
截取(req:HttpRequest,next:HttpHandler):可观察{
let范围:字符串;
//仅为以下作用域注入令牌
如果(请求url.indexOf('https://graph.microsoft.com') === 0) {
范围=https://graph.microsoft.com';
}
else if(请求url.indexOf('https://management.azure.com') === 0) {
范围=https://management.azure.com';
}
else if(req.url.indexOf(environment.apiUrl)==0){
scope=environment.appId;
}
如果(范围){
返回此.authService.getToken(scope.pipe)(
开关映射((令牌)=>{
让newReq;
如果(令牌){
const JWT=`Bearer${token}`;
newReq=req.clone({
集合标题:{
授权:JWT,
}
});
}
返回next.handle(newReq | | req);
})
);
}
否则{
返回next.handle(req);
}
}

所以问题出在我的身份验证服务的getToken函数中。我在归还代币后忘了完成可观察的!由于httpClient.get observable是通过我的getToken observable映射的开关,这导致我在onDownloadClicked中的订阅从未完成

// from my auth service
getToken(resource: string): Observable<string> {
  return Observable.create((observer: Observer<string>) => {
    this.context.acquireToken(resource, (error, token) => {
      if (token) {
        observer.next(token);
        observer.complete(); // this was missing
      }
      else {
        this.login();
      }
    });
  });
}
//来自我的身份验证服务
getToken(资源:字符串):可观察{
返回可观察的。创建((观察者:观察者)=>{
this.context.acquireToken(资源,(错误,标记)=>{
如果(令牌){
下一个(令牌);
observer.complete();//缺少此项
}
否则{
this.login();
}
});
});
}

无法在本地复制-当使用
{responseType:'blob'}
管道中的
finalize
创建
HttpClient#get
时,我看到已完成的回调被调用。按F12并告诉我们网络上有什么。你看到了什么反应?我试图制造一场闪电战。使用了所有库的相同版本,但我也不能复制它。它只在sb中起作用:@JohnPeters网络选项卡看起来很正常,请求代码为200,内容看起来很好。