我正在尝试使用ionic2 + angular2创建应用程序,我无法从服务器API获取帐户验证结果(0:失败1:成功)。
这是ResultCode类
export class ResultCode{
result: number;
}
这是服务代码
@Injectable()
export class LoginService{
private headers = new Headers({'Content-Type': 'application/json'});
constructor(private http:Http){ }
authenticate(url:string,email:string, password:string): Promise<ResultCode>{
return this.http
.get(url)
.toPromise()
.then(res => res.json() as ResultCode)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.result || { };
}
private handleError (error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
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);
}
这是LoginPage代码
export class LoginPage {
resultCode:ResultCode;
private loginForm : FormGroup;
constructor(
public navCtrl: NavController,
private loginService:LoginService,
private formBuilder: FormBuilder) {
this.loginForm = this.formBuilder.group({
email: ['',[Validators.required,Validators.email]],
password: ['',[Validators.required,Validators.minLength(6)]]
});
}
login(){
let email = this.loginForm.get('email').value;
let password = this.loginForm.get('password').value;
let url = `https://www.xxxx.com/api.pl?fn=login&email=${email}&password=${password}`;
this.authenticate(url,email,password);
console.log("result == " + this.resultCode.result);
}
authenticate(url,email,password){
this.loginService.authenticate(url,email,password)
.then(result=> this.resultCode = result);
}
}
我从控制台得到结果== undefined。
我可以得到结果
结果== 0 从控制台,如果我在.then()
内打印
authenticate(url,email,password){
this.loginService.authenticate(url,email,password)
.then(result=> console.log("result == " + result.result));
}
我想知道在authenticate()函数完成之前是否执行了console.log?谢谢你的帮助。
答案 0 :(得分:0)
让我们仔细看看我们的代码:
login() {
//...
this.authenticate(url,email,password);
console.log("result == " + this.resultCode.result);
//...
}
控制台打印result == undefined
的原因是因为在login()内部,您正在使用authenticate()
进行异步调用。 当运行时,程序其余部分的执行一直持续到console.log()
。因为console.log()的执行速度比使用authenticate()发出网络请求要快得多,所以它打印未定义,但稍后this.resultCode
内的值实际为0。
为了在程序中稍后处理响应,您必须等到它到达。因此,在网络请求完成后,您想要做的任何事情都需要在.then()
函数的authenticate()
部分内进行编码,如下所示:
authenticate (url,email,password){
this.loginService.authenticate(url,email,password)
.then((result) => {
// NOW WE ARE ALWAYS SURE THE RESPONSE HAS ARRIVED
this.resultCode = result
});
}
现在,由于你有同步函数login()调用异步authenticate(),你可能只想在 login()和之后做一些事情。
执行此操作的最佳方法是使用Promises。这就是我改变你的代码以支持它的方式:
login(){
let email = this.loginForm.get('email').value;
let password = this.loginForm.get('password').value;
let url = `https://www.xxxx.com/api.pl?fn=login&email=${email}&password=${password}`;
return new Promise((resolve, reject) => { // notice we now return a Promise here too
this.authenticate(url,email,password)
.then(result){
this.resultCode = result;
resolve (result);
}
};
}
authenticate(url,email,password){
return new Promise((resolve, reject) => { // notice we now return a Promise
this.loginService.authenticate(url,email,password)
.then((result) => { resolve(result)); } // notice the change here, resolving the value outwards to the caller
};
}
现在,在您的LoginPage代码中的任何其他位置,您希望运行完全登录后确定执行的代码,您可以这样做:
login().then(){
// NOW WE ARE SURE LOGIN HAS COMPLETED
}