我试图在我的http调用中放入一个进度条,但有些我怎么能够以异步方式进行同步HTTP调用请求。
以下是进行http呼叫的功能
public authenticationt2cHTTP(email, password) {
console.log("authenticationt2cHTTP WITH HEADERS");
const body = new HttpParams()
.set('email', email)
.set('password', password);
const req = new HttpRequest('POST', 'http://192.168.0.135:8080/rest/auth/login', body, {
reportProgress: true,
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
});
this.http.request(req).subscribe(event => {
// Via this API, you get access to the raw event stream.
// Look for upload progress events.
if (event.type === HttpEventType.UploadProgress) {
// This is an upload progress event. Compute and show the % done:
const percentDone = Math.round(100 * event.loaded / event.total);
console.log(`File is ${percentDone}% uploaded.`);
} else if (event instanceof HttpResponse) {
console.log('File is completely uploaded!');
}
});
}
下面是我在我的组件类中用于进行调用的代码,showload是用于显示/隐藏页面预加载器的临时变量。
this.showLoader = false;
var k = this.myhttpService.authenticationt2c(this.form.get("email").value, this.form.get("password").value);
this.showLoader = true;
答案 0 :(得分:1)
我使用以下http
服务包装器来访问不同的挂钩,例如handleResponse
,beforeRequest
,afterResponse
,onCatch
& onSuccess
。
API服务应该使用HttpInterceptor
包装器(它在内部触发http调用并允许访问上面提到的钩子)。
注意加载器逻辑是如何在beforeRequest
& afterResponse
挂钩。
import { Injectable } from "@angular/core";
import { XHRBackend, RequestOptions, Request, RequestOptionsArgs, Response, Http, Headers } from "@angular/http";
import { Store } from "@ngrx/store";
import { Observable } from "rxjs/Rx";
import { Observer } from "rxjs/Observer";
import { Response as ApiResponse } from "../../models/base/response.model";
import { ToastModel } from "../../redux/app-reducers";
import { ReducerActions } from "../../redux/reducer-actions";
@Injectable()
export class HttpInterceptor extends Http {
constructor(private _XHRBackend: XHRBackend,
private _RequestOptions: RequestOptions,
private _ToastStore: Store<ToastModel>,
private _LoaderStore: Store<boolean>) {
super(_XHRBackend, _RequestOptions);
}
public request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return this.handleResponse(super.request(url, options));
}
public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url);
return super.get(url, this.getRequestOptionArgs(options));
}
public post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url, body);
return super.post(url, body, this.getRequestOptionArgs(options));
}
public put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url, body);
return super.put(url, body, this.getRequestOptionArgs(options));
}
public delete(url: string, options?: RequestOptionsArgs): Observable<Response> {
this.beforeRequest(url);
return super.delete(url, this.getRequestOptionArgs(options));
}
private getRequestOptionArgs(options?: RequestOptionsArgs): RequestOptionsArgs {
if (options == null) {
options = new RequestOptions();
}
if (options.headers == null) {
options.headers = new Headers();
}
options.headers.append('Content-Type', 'application/json');
return options;
}
private handleResponse(response: Observable<Response>): Observable<Response> {
return response
.catch(this.onCatch)
.do(this.onSuccess.bind(this), this.onError.bind(this))
.finally(this.afterResponse.bind(this));
}
private beforeRequest(url: string, body?: string): void {
this._LoaderStore.dispatch({ type: ReducerActions.Loader.Set, payload: true });
}
private afterResponse(): void {
this._LoaderStore.dispatch({ type: ReducerActions.Loader.Set, payload: false });
}
private onCatch(error: any, caught: Observable<Response>): Observable<Response> {
console.log("interceptor catch called");
return Observable.throw(error);
}
private onSuccess(res: Response): void {
let response: ApiResponse<any> = res.json();
if (!response.message) {
return;
}
let toast: ToastModel = {
text: response.message,
duration: 5000,
type: "success"
};
this._ToastStore.dispatch({ type: ReducerActions.Toast.Update, payload: toast });
}
private onError(error: any): void {
let toast: ToastModel = {
text: "Error occurred!",
duration: 5000,
type: "failure"
};
this._ToastStore.dispatch({ type: ReducerActions.Toast.Update, payload: toast });
}
}
我希望这会有所帮助:)
答案 1 :(得分:1)
正如评论中所提到的,这是异步的,所以当请求需要一些时间来执行时,
this.showLoader = false;
// takes some time to execute
var k = this.myhttpService.authenticationt2c(...);
// executed while waiting for above code to execute
this.showLoader = true;
相反,从您的服务返回一个Observable并在组件订阅中。然后在回调(subscribe)内部切换布尔标志。我猜你要在请求完成后实际将布尔标志showLoader
切换到false
,所以我在下面切换它们:
this.showLoader = true;
this.myhttpService.authenticationt2c(...)
.subscribe(() => this.showLoader = false)
并且如上所述,从服务中返回一个Observable,因此请使用map
代替subscribe
:
this.http.request(req).map(event => { ... })
请查看以下链接,了解异步性:How do I return the response from an Observable/http/async call in angular2?和How do I return the response from an asynchronous call?