Angular rxjs Subject : 在发出值后订阅一个主题

Angular rxjs Subject : subscribing to a subject after emitting values

我读了一篇 article,其中指出,如果您在事件已经发出时订阅主题,您将失去发出的值。他的演示示例如下。

let subject: Subject<string> = new Subject();
subject.next('test');
 
subject.subscribe((event) => {
  console.log(event);
});

但是,我实现了类似的方法,其中第一个主题将发出值,然后订阅该主题。价值就在那里。没有丢失。代码如下。 在代码中,我们将身份验证信息保存在一个主题中。我们在 header 组件中使用它来显示注销按钮和链接。问题是为什么我的代码可以正常工作,即使文章说它不会?

import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Subject} from "rxjs";
import { User } from "./user.model";

@Injectable({providedIn : "root"})
export class AuthService{

    constructor(private httpClient:HttpClient){}
    
    user = new  Subject<User>();   //emit new user when login or logout or token expired

    login(email:string,password:string){
        return this.httpClient
       .post<SignUpResponse>('https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyBCK9B2RcL0D4Bn8YaFCxE9rBXejTLNYQY',
        {
            email:email,
            password:password,
            returnSecureToken:true
        })
       .pipe(tap( response => this.handleAuthentication(response.email,response.idToken,response.idToken,response.expiresIn)))
    }


    private handleAuthentication(email:string,userId:string,token:string,expiresIn:string){

         const expirationDate = new Date(new Date().getTime() + +expiresIn * 1000)
         const user = new User(email,userId,token,expirationDate);
         this.user.next(user);
    }
}

Header.component.ts

import { Component,Output, EventEmitter, OnInit, OnDestroy } from "@angular/core";
import { Subscription } from "rxjs";
import { AuthService } from "../auth/auth/auth.service";
import { DataStorageService } from "../shared/data-storage.service";

@Component({
    selector : 'app-header',
    templateUrl:'./header.component.html'
})

export class HeaderComponent implements OnInit,OnDestroy{

    collapsed = true;
    private subscription : Subscription;
    isAuthenticated : boolean = false;

    constructor(private dataStorageService:DataStorageService,
                private authService:AuthService){

    }

    ngOnInit(){
        this.subscription =  this.authService.user.subscribe( user => {
        this.isAuthenticated = !!user; 
        console.log("User Object"); console.log(user); 
        console.log("IsAuthenticated value");  console.log(!!user);
    })
   }

    ngOnDestroy(){
        this.subscription.unsubscribe();
    }
}

您的示例订阅 运行ning 的唯一原因是您在开始登录之前加载了 Header 组件 process/method。 ngOnInit 组件在服务中的 login 方法之前被调用。

您的代码 运行 与您在问题中描述的方式不同:

user = new  Subject<User>();
subject.next('test');

// then this runs in component ngOnInit 
this.authService.user.subscribe((event) => {
  console.log(event);
});

// when you try to login from inside the component then it runs the login method with next.
login(email:string,password:string){.....
this.user.next(user);  // now this is triggered hence you don't loose the user response.