如何在subscribe方法中解析数据之前使函数(调用subscribe方法)等待返回值?

问题描述 投票:1回答:2

我对Angular很新,并且在此感谢一些指导。我在AuthService中的userLoggedIn函数总是返回false,因为这个函数返回变量userIsLoggedIn的值,它最初被赋值为false,它永远不会到达代码块 - 在执行return语句之前传递给subscribe方法的回调函数中的this.userIsLoggedIn=res.tokenValid;。我相信这是由于javascript处理函数的异步性质,但是如何在完全执行我的回调函数之前阻止执行到达return语句,这样如果我的响应对象的validToken属性包含真值,我的函数可以返回true?

我尝试了以下但没有帮助:

  1. 在我的回调函数上使用async-await - this.httpReq.verifyToken(token) .subscribe(**async** res =>{ this.userIsLoggedIn= **await** res.tokenValid; })
  2. 使整个userLoggedIn函数async-await **async** userLoggedIn():boolean{ **await** this.httpReq.verifyToken(token) }
//Auth Service
export class AuthService {
    userIsLoggedIn=false;
    constructor(private router:Router, private repo:ProductRepository, 
        private httpReq:HttpRequestService) {}

    userLoggedIn():boolean{
        const token=this.getLocalToken();

        if(!token){
            return false;
        }

        this.httpReq.verifyToken(token)
            .subscribe(async res =>{
            this.userIsLoggedIn=await res.tokenValid;
            })

        return this.userIsLoggedIn;

    }
}


//verifyToken method in my HttpRequestService
export class HttpRequestService {

    constructor(private http: HttpClient) { }

    verifyToken(token:string){
        const headers=new HttpHeaders({
          'Content-Type':'application/json',
          'Authorization':token
        })

        return this.http.post<{message:string, tokenValid:boolean}>('http://localhost:3000/users/authenticate', null, {headers:headers})

    }
}
angular async-await subscribe
2个回答
1
投票

因为你的userLoggedIn()函数正在执行HTTP调用,所以这个函数应该是异步的(一段时间后完成)。

提示:要了解更好的sync vs async,请查看回调,async / await,promises,observables。

回答:

 userLoggedIn(): Observable<boolean>{
        // Make sure this is sync or need to be chained with the observable below
        const token = this.getLocalToken();

        if(!token){
            return of(false);
        } else {
            return this.httpReq.verifyToken(token).pipe(
                 // Use the tap operator to update some inner class variable
                 tap((res) => this.userIsLoggedIn = res.tokenValid)
                 // We do have the response, if there is ok you can return true. You can add additional validations.
                 switchMap((res) => res ? of(true) : of(false)),
                 // Catch errors, do something with them
                 catchError((err) => of(false))
            )
        }
    }

小词汇表:

of:创建一个新的observable提供的参数 tap:不影响流,可以执行没有响应的副作用的操作 switchMap:类似于.then(() => new Promise()

...最后调用函数:

   userLoggedIn().subscribe(isLoggedIn => console.log(isLoggedIn);

0
投票

您不需要使用异步或等待。 HttpRequestService.verifyToken返回类型为{message:string,tokenValid:boolean}的Observable。您可以让userLoggedIn函数也返回此Observable,然后对userLoggedIn进行订阅。你需要熟悉RX Observables,但你可以让HttpRequestService.verifyToken返回一个Promise。在这种情况下,这不是一个坏主意。

© www.soinside.com 2019 - 2024. All rights reserved.