是否可以控制角度服务的执行顺序?

时间:2019-05-20 12:21:29

标签: angular typescript dependency-injection

我正在构建Angular应用程序,但是我在服务中调用webapi路由时遇到了问题。

该应用程序必须在两个主要步骤中执行:

  1. 致电OAuth服务器并获取有效令牌。这是通过两条途径完成的: 一种。吸引观众 b。获取具有有效受众群体的令牌
  2. 一旦有了有效的令牌,就可以获取数据(例如,用户,待办事项列表...)

我的tokenService.ts

@Injectable({
    providedIn: 'root'
})
export class TokenService extends ServiceBase {

    public token$: Observable<string>;
    private _token: BehaviorSubject<string>;

    constructor(private http: HttpClient,
        public request: RequestBase,
        public router: Router) {

        this._token = new BehaviorSubject<string>('');
        this.token$ = this._token.asObservable();
    }


    generateToken(callback?: () => void, errorCallback?: (error: string) => void): void {
        // 1. get audience
        const audienceUrl = 'https://myoauthserverurl/api/audience';
        const postData = {
            // some data to post
        };
        const audienceHttpHeaders = new HttpHeaders({
            // some headers
        });

        this.request.post(audienceUrl, postData, audienceHttpHeaders).subscribe((audienceResponse: any) => {
            const audience = new Audience();
            audience.clone(audienceResponse);

            if (!audience.error.isNullOrEmpty()) {
                return;
            } else {
                // 2. get token with audience response
                const tokenUrl = 'https://myoauthserverurl/oauth2/token';
                const tokenPostData = ``;
                const tokenHttpHeaders = new HttpHeaders({
                    // some headers
                });

                this.request.post(tokenUrl, tokenPostData, tokenHttpHeaders, false).subscribe((tokenResponse: any) => {
                    const token = new Token();
                    token.clone(tokenResponse);

                    if (!token.error.isNullOrEmpty()) {
                        console.log('Token generation failed: ' + token.error_description);

                        if (errorCallback !== null) {
                            errorCallback(token.error_description);
                            return;
                        }
                    }

                    this.setToken(token.access_token);

                    if (callback !== null) {
                        callback();
                    }

                });
            }

        });

    }

    public setToken(token: string) {
        this._token.next(token);
    }
    public getToken() {
        return this._token.getValue();
    }

}

我的app.component.ts调用

tokenService.generateToken();

然后我加载一些组件(例如,UsersComponent.ts),并显示我的用户列表。在UsersComponent.ts构造函数中,我注入了用户服务:

constructor(public userService: UserService) {
    // do something
}

UserService.ts

@Injectable({
    providedIn: 'root'
})
export class UserService {

    users$: Observable<User[]>;
    _users: BehaviorSubject<User[]>;

    constructor(private http: HttpClient,
        public request: RequestBase,
        public tokenService: TokenService) {

        this._users = new BehaviorSubject([]);
        this.users$ = this._users.asObservable();

        this.List();
    }

    public getUsers() {
        this._users.value;
    }

    public setUsers(value: User[]) {
        this._users.next(value);
    }

    public List() {
        this._users.next([]);

        this.tokenService.token$.subscribe(token => {
            const url = `https://webapi.url/users/list`;
            const httpHeaders = new HttpHeaders({...
                'mysecuredtoken': this.tokenService.getToken()
            });

            this.request.get(url, httpHeaders).subscribe((data: any) => {
                const response = data as User[];
                if (response !== null) {
                    this._users.next(response);
                }
            });
        });
    }
}

但是会发生什么:

  1. 致电观众路线
  2. 呼叫用户/列表路由
  3. 调用令牌路由

我该如何控制这些服务

  1. 观众的呼唤
  2. 调用令牌
  3. 呼叫用户/列表

我希望它足够清楚:) 感谢您的帮助。

[编辑] 感谢 this.tokenService.token $ .subscribe(...)用户/列表路由异步调用(因此一段时间后可以),但在此之前也就是说,有很多呼叫用户/列表路由。我想避免这种行为,并干净地调用我的webapi路由。 但是由于事情是异步调用的,这值得吗?

[编辑] 这个问题已经解决

1 个答案:

答案 0 :(得分:0)

您正在使用BehaviorSubject,它将返回您在此处设置的初始值:

this._token = new BehaviorSubject<string>('');

您的订阅this.tokenService.token$.subscribe...将立即被调用,值为”。

请尝试使用BehaviorSubject,而不要使用Subject