我遵循了“英雄之旅”角色教程,可以应用相同的机制从网络服务中检索项目列表并将其显示在表格中。
现在我正在编写一个调用Web服务来检查凭据的函数。此Web服务返回一行:{ "msg": "Hello username" }
login.component.html :
[...]
<a class="btn rounded-btn" [routerLink]="['/dashboard']" (click)="onLogIn(loginForm)"> Log in </a>
[...]
login.component.ts :
export class LoginComponent implements OnInit {
constructor(public router: Router,
private loginService: LoginService) {}
ngOnInit() {
}
onLogIn(loginForm: any) {
let authResponse = this.loginService.check_credentials(loginForm.controls.login.value, loginForm.controls.password.value);
console.log(authResponse)
localStorage.setItem('isLoggedin', 'true');
}
login.service.ts :
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class LoginService {
private wsLoginUrl = '/api/check_login';
wsResponse;
constructor(private http: HttpClient) { }
check_credentials(login: string, password: string): string {
this.getResponse().subscribe(response => this.wsResponse = response);
this.getResponse().subscribe(response => console.log(response));
console.log(this.wsResponse);
return "ok"
}
getResponse() {
return this.http.get(this.wsLoginUrl);
}
}
控制台输出是:
undefined login.service.ts:43:12
ok login.component.ts:25:8
Object { msg: "Hello username" } login.service.ts:34:53
由于'ok'在webservice响应之前,我想一旦subscribe(...)
完成,功能代码就会继续。然后,当webservice响应时,执行订阅代码:console.log(response)
和this.wsResponse = response
。
如何创建一个等待webservice响应的函数?
我尝试了不同的方法,使用map()或其他SO答案,但我找不到如何做到这一点。
更新了代码,感谢RubénSoler现在的答案:
login.service.ts :
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable()
export class LoginService {
private wsLoginUrl = '/api/check_login';
constructor(private http: HttpClient) { }
async checkCredentials(login: string, password: string) {
try {
let response = await this.getResponse().toPromise();
return response;
} catch(e) {
console.error(e);
}
}
getResponse() {
return this.http.get(this.wsLoginUrl);
}
}
login.component.ts :
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { routerTransition } from '../router.animations';
import { FormGroup, FormControl } from '@angular/forms';
import { LoginService } from './login.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss'],
animations: [routerTransition()]
})
export class LoginComponent implements OnInit {
constructor(public router: Router,
private loginService: LoginService) {}
ngOnInit() {
}
onLogIn(loginForm: any) {
this.loginService.checkCredentials(loginForm.controls.login.value, loginForm.controls.password.value)
.then((resp) => {
if (resp['msg'] == 'hello') {
console.log('Resp is ok')
localStorage.setItem('isLoggedin', 'true');
this.router.navigate(['dashboard']);
}
else {
console.log('Resp is NOT ok')
//Other things...
}
} );
}
}
答案 0 :(得分:1)
该应用程序正常运行,但您只需要分析执行流程。
首先打印undefined
,因为第一个订阅仍在等待。
console.log(this.wsResponse);
第二个打印正常,因为return 'ok'
函数中check_credentials
(重合),并在使用它时在组件中打印。
let authResponse = this.loginService.check_credentials(loginForm.controls.login.value, loginForm.controls.password.value);
console.log(authResponse)
之后,订阅者获得响应并在check_credentials
异步执行成功函数并打印{ msg: "Hello username" }
:
this.getResponse().subscribe(response => this.wsResponse = response);
this.getResponse().subscribe(response => console.log(response));
如果你想等待check_credentials
函数中的响应,你可以将observable转换为promise并使用async/await
这样的(login.service.ts):
async check_credentials(login: string, password: string): string {
try {
let response = await this.getResponse().toPromise();
this.wsResponse = response;
return response
} catch(e) {
console.error(e);
}
}
login.component.ts:
onLogIn(loginForm: any) {
this.loginService.check_credentials(loginForm.controls.login.value, loginForm.controls.password.value)
.then((res) => console.log(authResponse))
}
您可以在此处详细了解:https://medium.com/@benlesh/rxjs-observable-interop-with-promises-and-async-await-bebb05306875
和https://ponyfoo.com/articles/understanding-javascript-async-await