Можно ли контролировать порядок выполнения угловых сервисов? - PullRequest
0 голосов
/ 20 мая 2019

Я создаю приложение Angular, и у меня есть проблема с вызовами моих маршрутов webapi в моих службах.

Заявка должна быть выполнена в два основных этапа:

  1. Позвоните на OAuth-сервер и получите действительный токен. Это делается двумя путями: а. Получить аудиторию б. Получить токен с действительной аудиторией
  2. Как только у меня есть действующий токен, я могу получить свои данные (например, пользователи, список задач ...)

my 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. Звонок пользователей / список

Надеюсь, это достаточно понятно :) Спасибо за вашу помощь.

[EDIT] Благодаря this.tokenService.token $ .subscribe (...) users / list маршрут вызывается асинхронно (и через некоторое время все будет в порядке), но до этого, Есть много звонков на маршрут users / list . Я хотел бы избежать такого поведения и иметь чистые звонки на мои маршруты вебапи. Но как вещи называются асинхронно, стоит ли это того?

[EDIT] этот вопрос РАЗРЕШЕН

1 Ответ

0 голосов
/ 20 мая 2019

Вы используете BehaviorSubject, который будет возвращать начальное значение, которое вы устанавливаете здесь:

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

Ваша подписка this.tokenService.token$.subscribe... будет вызвана сразу, с пустым значением ''.

Вместо использования BehaviorSubject попробуйте использовать Subject.

...