Angular 2等待嵌套的observable完成

时间:2017-09-15 10:26:25

标签: angular

在导航到另一个页面之前,我需要等待两个嵌套的Observable完成。 我不知道什么是最好的方法,因为它们是嵌套的,因此我在Angular应用程序中遇到了同步问题。 Observable正在我的身份验证服务中设置。 authentication.service.ts:

login(username: string, password: string) {
        let reqUrl = AppSettings.__USER_TOKEN_URL;
        let reqHeaders = this.authConfig.token.headers;
        let reqBody = encodeURI(
            this.authConfig.token.body
                .replace(/{{ username }}/g, username)
                .replace(/{{ password }}/g, password));

        //
        // Get token, then get user identity, if login successfull.
        //

        return this.http.post(reqUrl, reqBody, reqHeaders)
            .map((response) => this.getIdentity(response))
            .catch(this.handleErr);
    }

private getIdentity(response: Response) {

        //
        // Get user identity based on token.
        //

        let body = response.json();
        let token = body.access_token;

        if (null != token && undefined != token) {
            this.authConfig
                .identity
                .headers
                .headers.set('authorization', 'Bearer ' + token);

            let reqUrl = AppSettings.__USER_IDENTITY_URL
            let reqHeaders = this.authConfig.identity.headers;
            let reqbody = this.authConfig.identity.body;

            return this.http.post(reqUrl, reqbody, reqHeaders)
                .map((response) => this.setUser(response))
                .catch(this.handleErr)
                .subscribe();
        }
    }

然后在我的Login组件中,我试图调用服务 login()方法,当它完成时,我想导航到另一个实例。 login.component.ts

login() {
        this.loading = true;
        this.authenticationService.login(this.model.username, this.model.password).subscribe(
            data => { },
            error => { console.log('Error authenticating: ' + error); },
            () => {  this.router.navigate([this.returnUrl]) });
    }

但它没有用。触发router.navigate时,Observable仍在运行。 一个Angular新秀的想法? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

问题是你只是在subscribe内调用getIdentity()而不会使两个observable 顺序

相反,您需要返回observable而不是订阅对象并使用switchMap

<强> getIdentity

private getIdentity(response: Response) {

        //
        // Get user identity based on token.
        //

        let body = response.json();
        let token = body.access_token;

        if (null != token && undefined != token) {
            this.authConfig
                .identity
                .headers
                .headers.set('authorization', 'Bearer ' + token);

            let reqUrl = AppSettings.__USER_IDENTITY_URL
            let reqHeaders = this.authConfig.identity.headers;
            let reqbody = this.authConfig.identity.body;

            return this.http.post(reqUrl, reqbody, reqHeaders)
                .map((response) => this.setUser(response))//return observable.
        }
}

在登录电话中:

return this.http.post(reqUrl, reqBody, reqHeaders)
        .switchMap((response) => this.getIdentity(response))
        .catch(this.handleErr);

switchMap将切换到第二个observable并在完成第一个observable时返回。