You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 4中loading.dismiss()在handleError()方法中失效求助

嘿,我懂你遇到的问题啦——你想让加载提示框不管请求成功还是失败都能正常关闭,但不知道怎么在错误处理的场景里调用loading.dismiss()对吧?其实不用纠结在handleError里单独处理,我们可以用RxJS的操作符来统一搞定这个逻辑!

解决方案:用RxJS操作符统一处理加载框关闭

最优雅的方式是利用RxJS的finally(RxJS 5及以下)或finalize(RxJS 6+)操作符,它们会在Observable的生命周期结束时(不管是正常完成还是抛出错误)执行指定逻辑,这样就能确保加载框一定会被关闭,不用在成功回调和错误处理里重复写代码。

修改后的完整代码示例(RxJS 5及以下)

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/finally';
import { LoadingController } from 'ionic-angular';

@Injectable()
export class SharedProvider {
  private _postsURL = "https://jsonplaceholder.typicode.com/posts";

  constructor(private http: Http, public loadingCtrl: LoadingController) { }

  getPosts(): Observable<IPosts[]> {
    let loading = this.loadingCtrl.create({ content: 'loading...' });
    loading.present();

    return this.http.get(this._postsURL)
      .map((response: Response) => {
        return <IPosts[]>response.json();
      })
      .catch(this.handleError)
      // 核心:不管请求成功/失败,都会执行这里的关闭逻辑
      .finally(() => {
        loading.dismiss();
      });
  }

  private handleError(error: Response | any) {
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    console.error(errMsg);
    return Observable.throw(errMsg);
  }
}

如果用的是RxJS 6+版本

RxJS 6+对操作符的导入和使用方式做了调整,需要用pipe来组合操作符,且操作符名称改为finalize:

import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs';
import { map, catchError, finalize } from 'rxjs/operators';
import { LoadingController } from 'ionic-angular';

@Injectable()
export class SharedProvider {
  private _postsURL = "https://jsonplaceholder.typicode.com/posts";

  constructor(private http: Http, public loadingCtrl: LoadingController) { }

  getPosts(): Observable<IPosts[]> {
    let loading = this.loadingCtrl.create({ content: 'loading...' });
    loading.present();

    return this.http.get(this._postsURL).pipe(
      map((response: Response) => <IPosts[]>response.json()),
      catchError(this.handleError),
      finalize(() => loading.dismiss())
    );
  }

  private handleError(error: Response | any) {
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    console.error(errMsg);
    return throwError(() => errMsg);
  }
}

为什么这个方法有效?

  • finally/finalize操作符会监听Observable的整个生命周期,不管请求是成功完成还是抛出错误,都会触发回调函数,所以加载框100%会被关闭。
  • 这种写法避免了重复代码,也不用把loading变量传递到handleError方法里,逻辑更清晰简洁。

内容的提问来源于stack exchange,提问作者Jayesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:48:57