2016-08-24 195 views
1

我有一個同步操作在RxJS observables訂閱鏈的某處運行。同步操作問題RxJS observables訂閱

這個同步操作設置了爲了執行http調用(異步/可觀察)而需要進一步向下鏈的本地存儲(同步)數據。

下面是該序列的摘要:

  1. 異步操作返回一個可觀察到的所謂
  2. 同步操作設置在本地存儲器上的數據
  3. 使用本地存儲的日期和返回一個可觀察到的
  4. 異步操作最終認購

當時3.被調用,看起來數據在本地存儲上不可用 - 應該已經設置爲2.

以上只是對問題的簡化。

以下是完整的代碼(在打字稿):從SessionService

resetPassword(passwordResetForm) { 
    return this.http.put(this.urls.USER_ACCOUNT.RESET_PASSWORD, passwordResetForm); 
    } 

這是通過一個形式(位於一個組件)稱爲:

resetPassword() { 
    this.submitted = true; 
    if (this.passwordResetForm.valid) { 
     this.route.params.map(params => params['userAccountToken']) 
     .switchMap(userAccountToken => { 
      return Observable.concat(
      this.userAccountService.resetPassword(Object.assign(this.passwordResetForm.value.passwordReset, {token: userAccountToken})), 
      this.sessionService.signinByUserAccountToken(userAccountToken) 
     ); 
     }) 
     //Will require the UserAccountResolve below which will itself fail because 'x-auth-token' is not yet available on local storage 
     .subscribe(() => this.router.navigate(['/dashboard'])); 
    } 
    } 

從UserAccountService :

signinByUserAccountToken(userAccountToken: string) { 
    return this.http.post(format(this.urls.AUTHENTICATION.SIGNIN_BY_USER_ACCOUNT_TOKEN, {userAccountToken}), null) 
     .do(response => this.setPersonalInfo(response.headers.get('x-auth-token'))); 
    } 

    private setPersonalInfo(sessionToken) { 
    localStorage.setItem('authenticated', 'true'); 
    localStorage.setItem('sessionToken', sessionToken); 
    this.authenticated$.next(true); 
    } 

UserAccountResolve:

import {Injectable} from '@angular/core'; 
import {Resolve, ActivatedRouteSnapshot} from '@angular/router'; 
import {UserAccount} from '../shared/models/useraccount.model'; 
import {AuthenticatedHttpClient} from '../shared/services/authenticated-http-client.service'; 
import {URLS} from '../urls/URLS'; 

@Injectable() 
export class UserAccountResolve implements Resolve<UserAccount> { 

    private urls; 

    constructor(private authenticatedHttpClient: AuthenticatedHttpClient) { 
    this.urls = URLS; 
    } 

    resolve(route: ActivatedRouteSnapshot) { 
    //Will fail 
    return this.authenticatedHttpClient.get(this.urls.USER_ACCOUNT.USER_ACCOUNT) 
     .map(response => response.json()); 
    } 

} 

AuthenticatedHttpClient:

@Injectable() 
export class AuthenticatedHttpClient { 

    static createAuthorizationHeader(headers: Headers) { 
    //Is not available on local storage when required 
    headers.append('x-auth-token', localStorage.getItem('sessionToken')); 
    } 

    constructor(private http: Http) { 
    } 


    get(url) { 
    let headers = new Headers(); 
    AuthenticatedHttpClient.createAuthorizationHeader(headers); 
    return this.http.get(url, { 
     headers: headers 
    }); 
    } 
    ... 

是否有人可以幫忙嗎?

回答

0

如果我正確理解你的問題,你想延遲重定向你的用戶,直到兩個HTTP請求完成。目前,您訂閱了Observable,一旦它觀察到第一個結果(在本例中爲userAccountService.resetPassword()的結果),就會立即發生重定向。

如果你只是想等待所有請求完成,你可以訂閱onCompleted這樣的:

observable.subscribe(
    _ => {}, 
    err => { /* Don't forget to handle errors */ }, 
    () => this.router.navigate(['/dashboard'])) 

但是有一個可觀察其結果,你不關心是一個標誌,你的應用程序可能需要這些日子之一是重構。