如何在angular5中进行同步调用?
How to make a synchronous call in angular 5?
所以,我试图找到这个问题的解决方案。但是,不知何故我无法这样做,可能是因为缺乏 angular 5 中的知识。
这是我的服务:
GetCurrentUserData(): Observable<ResponseData> {
return this.http.get<ResponseData>(ApplicationURLS.GetCurrentUserInformation)
.map(response => {
return response;
});
//.catch(error => this.handleError(error));
}
这是我的组件:
public GetCurrentUserInformation(): any {
return this.loginService.GetCurrentUserData().subscribe(data => { return data; });
}
我在这里尝试访问数据:
ngAfterViewInit() {
debugger;
this.responseData = this.GetCurrentUserInformation();
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
}
当我检查 this.responseData 时,它总是返回这个而不是我想要的数据:
我只想进行一次同步调用,以便立即获取数据。
我也尝试在服务中使用 do() 但它返回的 do() 不是函数。
异步函数不能被同步调用,因为它们是异步的。
subscribe
通常不应在预期被链接的方法中执行。即使应该,也应该从方法返回可观察的而不是订阅(订阅可以另外保存以在销毁时取消订阅)。
GetCurrentUserInformation
方法是多余的,因为它只是服务调用的包装器。代码可以重构为:
ngAfterViewInit() {
this.loginService.GetCurrentUserData().subscribe(data => {
this.responseData = data;
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
}
订阅 GetCurrentUserData()
http 调用是异步的(每个浏览器 api 调用都是异步的,因为 javascript 引擎在单个线程中运行(google 对于浏览器更多事件循环,这不是 angular 问题))
this.GetCurrentUserInformation().subscribe((data: ResponseData) => {
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
为了确保在处理响应之前执行异步调用,您可以使用来自 ReactiveX 的 Observable.forkJoin()。
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
Observable.forkJoin(
this.http.get('/links.json').map((response:Response) => response.json()),
this.http.get('/bookmarks.json').map((response:Response) => response.json())
).subscribe(
data => {
this.links = data[0]
this.bookmarks = data[1]
},
error => console.error(error)
);
subscribe() 函数的 onNext 处理程序将在所有 HTTP 请求成功完成时执行。
同步调用没有直接的方法,但是可以按照下面的步骤进行(这段代码写在angular7)。
import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http';
export class SampleComponent implements OnInit {
Request1result:Object;
Request2result:Object;
constructor(private http:HttpClient) { }
ngOnInit()
{
this.http.get("URL1").subscribe((res)=>{
this.Request1result=res;
this.after1(); // execution will move to next request only when first is done.
});
}
after1()
{
this.http.get("URL2").subscribe((res)=>{
this.Request2result=res;
this.after2(); // execution will move to the rest of the code only when both the requests are done.
});
}
after2()
{
// rest of the code.
console.log(this.Request1result);
console.log(this.Request2result);
}
}
这可以通过使用 async/await
来简化
public GetCurrentUserInformation(): Promise<any>{
return this.loginService.GetCurrentUserData().toPromise()
}
ngAfterViewInit
async ngAfterViewInit() {
this.responseData = await this.GetCurrentUserInformation(); // ♂️
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
}
使用同步 http 请求如下
var request = new XMLHttpRequest();
request.open('GET', "https://domain/api", false);
request.send(null);
const response = JSON.parse(request.responseText);
使用 HttpClient
将无法利用 DI,因此应在需要时绝对使用。
使调用同步的最佳方法是使用订阅的完整方法。
source$.subscribe({ next: doSomething, error: doSomethingElse,
complete: lol }).
如果我们订阅了一些东西,订阅完成后想做一些操作,那么我们就可以把代码写完整了。
所以,我试图找到这个问题的解决方案。但是,不知何故我无法这样做,可能是因为缺乏 angular 5 中的知识。 这是我的服务:
GetCurrentUserData(): Observable<ResponseData> {
return this.http.get<ResponseData>(ApplicationURLS.GetCurrentUserInformation)
.map(response => {
return response;
});
//.catch(error => this.handleError(error));
}
这是我的组件:
public GetCurrentUserInformation(): any {
return this.loginService.GetCurrentUserData().subscribe(data => { return data; });
}
我在这里尝试访问数据:
ngAfterViewInit() {
debugger;
this.responseData = this.GetCurrentUserInformation();
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
}
当我检查 this.responseData 时,它总是返回这个而不是我想要的数据:
我只想进行一次同步调用,以便立即获取数据。
我也尝试在服务中使用 do() 但它返回的 do() 不是函数。
异步函数不能被同步调用,因为它们是异步的。
subscribe
通常不应在预期被链接的方法中执行。即使应该,也应该从方法返回可观察的而不是订阅(订阅可以另外保存以在销毁时取消订阅)。
GetCurrentUserInformation
方法是多余的,因为它只是服务调用的包装器。代码可以重构为:
ngAfterViewInit() {
this.loginService.GetCurrentUserData().subscribe(data => {
this.responseData = data;
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
}
订阅 GetCurrentUserData()
http 调用是异步的(每个浏览器 api 调用都是异步的,因为 javascript 引擎在单个线程中运行(google 对于浏览器更多事件循环,这不是 angular 问题))
this.GetCurrentUserInformation().subscribe((data: ResponseData) => {
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
});
为了确保在处理响应之前执行异步调用,您可以使用来自 ReactiveX 的 Observable.forkJoin()。
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
Observable.forkJoin(
this.http.get('/links.json').map((response:Response) => response.json()),
this.http.get('/bookmarks.json').map((response:Response) => response.json())
).subscribe(
data => {
this.links = data[0]
this.bookmarks = data[1]
},
error => console.error(error)
);
subscribe() 函数的 onNext 处理程序将在所有 HTTP 请求成功完成时执行。
同步调用没有直接的方法,但是可以按照下面的步骤进行(这段代码写在angular7)。
import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http';
export class SampleComponent implements OnInit {
Request1result:Object;
Request2result:Object;
constructor(private http:HttpClient) { }
ngOnInit()
{
this.http.get("URL1").subscribe((res)=>{
this.Request1result=res;
this.after1(); // execution will move to next request only when first is done.
});
}
after1()
{
this.http.get("URL2").subscribe((res)=>{
this.Request2result=res;
this.after2(); // execution will move to the rest of the code only when both the requests are done.
});
}
after2()
{
// rest of the code.
console.log(this.Request1result);
console.log(this.Request2result);
}
}
这可以通过使用 async/await
public GetCurrentUserInformation(): Promise<any>{
return this.loginService.GetCurrentUserData().toPromise()
}
ngAfterViewInit
async ngAfterViewInit() {
this.responseData = await this.GetCurrentUserInformation(); // ♂️
if (this.responseData.code != responseCodes.success) {
this.googleInit();
}
}
使用同步 http 请求如下
var request = new XMLHttpRequest();
request.open('GET', "https://domain/api", false);
request.send(null);
const response = JSON.parse(request.responseText);
使用 HttpClient
将无法利用 DI,因此应在需要时绝对使用。
使调用同步的最佳方法是使用订阅的完整方法。
source$.subscribe({ next: doSomething, error: doSomethingElse, complete: lol }).
如果我们订阅了一些东西,订阅完成后想做一些操作,那么我们就可以把代码写完整了。