2016-09-22 246 views
2

以下是我的代码,我想login()authenticated()函数等待getProfile()函数完成其执行。我尝试了许多方法,如承诺等,但我无法实现它。请给我解决方案。如何等待函数在角度2中完成其执行。

import { Injectable }  from '@angular/core'; 
import { tokenNotExpired } from 'angular2-jwt'; 
import { myConfig }  from './auth.config'; 

// Avoid name not found warnings 
declare var Auth0Lock: any; 

@Injectable() 
export class Auth { 
    // Configure Auth0 
    lock = new Auth0Lock(myConfig.clientID, myConfig.domain, { 
    additionalSignUpFields: [{ 
     name: "address",        // required 
     placeholder: "enter your address",   // required 
     icon: "https://example.com/address_icon.png", // optional 
     validator: function(value) {     // optional 
     // only accept addresses with more than 10 chars 
     return value.length > 10; 
     } 
    }] 
    }); 

    //Store profile object in auth class 
    userProfile: any; 

    constructor() { 
    this.getProfile(); //I want here this function to finish its work 
    } 


    getProfile() { 
    // Set userProfile attribute if already saved profile 
    this.userProfile = JSON.parse(localStorage.getItem('profile')); 

    // Add callback for lock `authenticated` event 
    this.lock.on("authenticated", (authResult) => { 
     localStorage.setItem('id_token', authResult.idToken); 

     // Fetch profile information 
     this.lock.getProfile(authResult.idToken, (error, profile) => { 
     if (error) { 
      // Handle error 
      alert(error); 
      return; 
     } 

     profile.user_metadata = profile.user_metadata || {}; 
     localStorage.setItem('profile', JSON.stringify(profile)); 
     this.userProfile = profile; 
     }); 
    }); 
    }; 

    public login() { 
    this.lock.show(); 
    this.getProfile(); //I want here this function to finish its work 
    }; 

    public authenticated() { 
    this.getProfile(); //I want here this function to finish its work 
    return tokenNotExpired(); 
    }; 

    public logout() { 
    // Remove token and profile from localStorage 
    localStorage.removeItem('id_token'); 
    localStorage.removeItem('profile'); 
    this.userProfile = undefined; 
    }; 
} 
+0

你的getProfile函数应该返回一个promise/observable,然后登录和认证将能够连接到promise/observable,并在完成后执行动作 – galvan

回答

5

就像你在评论中看到的,你必须使用PromiseObservable来实现这一点,因为你的行为是非常简单的,你应该使用Promise因为Observable会有很多你不需要的功能这个案例。

这里是Promise版本的服务:

import { Injectable }  from '@angular/core'; 
import { tokenNotExpired } from 'angular2-jwt'; 
import { myConfig }  from './auth.config'; 

// Avoid name not found warnings 
declare var Auth0Lock: any; 

@Injectable() 
export class Auth { 
    // Configure Auth0 
    lock = new Auth0Lock(myConfig.clientID, myConfig.domain, { 
    additionalSignUpFields: [{ 
     name: "address",        // required 
     placeholder: "enter your address",   // required 
     icon: "https://example.com/address_icon.png", // optional 
     validator: function(value) {     // optional 
     // only accept addresses with more than 10 chars 
     return value.length > 10; 
     } 
    }] 
    }); 

//Store profile object in auth class 
userProfile: any; 

constructor() { 
    this.getProfile(); //I want here this function to finish its work 
    } 


getProfile():Promise<void> { 
    return new Promise<void>(resolve => { 
    // Set userProfile attribute if already saved profile 
    this.userProfile = JSON.parse(localStorage.getItem('profile')); 

    // Add callback for lock `authenticated` event 
    this.lock.on("authenticated", (authResult) => { 
     localStorage.setItem('id_token', authResult.idToken); 

     // Fetch profile information 
     this.lock.getProfile(authResult.idToken, (error, profile) => { 
     if (error) { 
      // Handle error 
      alert(error); 
      return; 
     } 

     profile.user_metadata = profile.user_metadata || {}; 
     localStorage.setItem('profile', JSON.stringify(profile)); 
     this.userProfile = profile; 
     resolve() 
     }); 
    }); 
    }) 
}; 

public login(): Promise<void>{ 
    this.lock.show(); 
    return this.getProfile(); //I want here this function to finish its work 
    }; 

    public authenticated():void{ 
    this.getProfile().then(() => { 
     return tokenNotExpired(); 
    }); 
    }; 

    public logout():void { 
    // Remove token and profile from localStorage 
    localStorage.removeItem('id_token'); 
    localStorage.removeItem('profile'); 
    this.userProfile = undefined; 
    }; 
} 

更多关于Promisehere

+0

我收到以下警告和它的仍然无效: - lock.min.js:2(节点)警告:可能发生EventEmitter内存泄漏。添加了11位听众。使用emitter.setMaxListeners()来增加限制。 –

+0

这不是一个错误,而是一个警告,因为你添加了太多的侦听器,你可能会发生内存泄漏,所以你应该检查你的代码质量(因为在循环中创建的侦听器,你经常会发现这种错误)。 – Supamiu

1

我会建议您设置getProfile返回一个可观察的。然后你的其他功能可以订阅该功能,并在订阅功能中执行他们的操作。 Angular 2 HTTP tutorial给出了一个例子