【问题标题】:Angular Http Request .subscribe() cause an infinite loopAngular Http Request .subscribe() 导致无限循环
【发布时间】:2018-05-06 22:16:15
【问题描述】:

我想在文件auth.service.ts 中编写一个函数loggedIn() 来检查本地存储中的令牌,然后在服务器端使用firebase/php-jwt 进行验证。但是 Typescript 中的代码给出了一个无限循环。这是我的代码:

auth.service.ts

loggedIn(){

    const token: string = localStorage.getItem('id_token');    

    if (token == null) {
      return false;
    }

    else {
      const subs = this.http.post('http://localhost/url/to/myPHP.php', {"token":token})
      .map(res=>res.json()).subscribe(data=>{
        if(data.valid){
          this.valid = true;
        } else {
          this.valid = false;
        }
      },
    err=>console.log(err));

      if (this.valid){
        console.log("Valid");
        return true;
      } else {
        console.log("Invalid");
        return false;
      }
    }
  }

给定令牌:有效令牌。
结果:没有给出错误,但有无限的“有效”console.log 并返回 true,直到 Apache 宕机。
给定令牌:无效令牌
结果:没有错误但无限的 console.log 'Invalid' 并返回 false,直到 Apache 宕机。

我尝试过的:

    loggedIn(){
        const token: string = localStorage.getItem('id_token');

        if (token == null) {
          return false;
        }

        else {
          const subs = this.http.post('http://localhost/url/to/myPHP.php', {"token":token})
          .map(res=>res.json()).subscribe(data=>{
            if(data.valid){
              this.valid = true;
            } else {
              this.valid = false;
            }
          },
        err=>console.log(err));

          if (this.valid){
            console.log("Valid");
            console.log(this.valid);
            return true;
          } else {
            console.log("Invalid");
            console.log(this.valid);
            return false;
          }
          subs.unsubscribe();
          return true;
        }
      }

subs.unsubscribe(); 行确实停止了循环,但它实际上会取消订阅Observable<Response>,并且.subscribe() 中的代码将不会运行。请帮忙。

编辑loggedIn()的用法

*ngIf="authService.loggedIn() 

在导航栏组件中 4 次。

内部auth.guard.ts

canActivate(){
        if (this.authService.validToken){
            return true;
        } else {
            this.router.navigate(['/login']);
            return false;
        }
    }

app.module.ts
{path:'profile', component:ProfileComponent, canActivate:[AuthGuard]}

【问题讨论】:

  • 您是否跟踪过您的loggedIn() 方法被调用了多少次?您是否在模板中使用过 ngIf="loggedIn()" 之类的东西,每次报价都会被评估?
  • 是的,我 dd,它被调用了 5 次。包括'ngIf'
  • 在您的ngOnInit() 中调用一次,设置一个局部变量,然后引用该变量而不是模板中的方法。
  • 取决于您的应用程序的其余部分是什么样的。不过应该很容易追踪。
  • @RobbyCornelissen 谢谢你的建议,我试试看。

标签: http post token jwt angular5


【解决方案1】:

我终于解决了这个问题。
我的代码的问题.subscribe() 是一个异步调用(实际上已安排为最后/稍后执行)。情况是这样的:
ngOnInit(): 位于组件 文件中

  ngOnInit(){
    this.authService.loggedIn();
    console.log("10");
  }

loggedIn() : 位于 auth.service.ts 文件中

  loggedIn(){

        const token: string = localStorage.getItem('id_token');    

        if (token == null) {
          return false;
        }

        else {
          const subs = this.http.post('http://localhost/url/to/myPHP.php', {"token":token})
          .map(res=>res.json()).subscribe(data=>{
            if(data.valid){
              console.log("1");
            } else {
              console.log("2");
            }

            console.log("3")
          },
        err=>console.log(err));
        }
      }

然后结果将是:
10
1
3
这意味着,您在订阅中所做的任何事情都只会在您需要之后才会更改(在许多情况下)。所以我们需要在subscribe() 中做任何我们需要做的事情,并且只在需要时触发它。就我而言,如果有任何更改适用于本地存储中的令牌,我想触发它​​。

这是我的解决方案

我希望它总是检查令牌。我用DoCheck()

内部auth.service.ts

verifyToken(authToken) {
    const body = {token:authToken};

    return this.http.post('http://localhost/url/to/myPHP.php',body)
    .map(res => res.json());
  }


tokenExist(): boolean {
    const token: string = localStorage.getItem('id_token');

    if (token == null) {
      return false;
    } else {
      return true;
    }
  }

内部navbar.component.ts

  ngOnInit() {
    this.curToken = localStorage.getItem('id_token');
    this.loggedIn(this.curToken);
  }

  ngDoCheck(){
    if (this.curToken != localStorage.getItem('id_token')){
      this.curToken = localStorage.getItem('id_token');
      this.loggedIn(this.curToken);
    }
  }

  loggedIn(token){
    if(this.authService.tokenExist()){
      this.authService.verifyToken(token).subscribe(data=>{
        if(data.valid){
          this.validLogin = true;
        } else {
          console.log("Invalid Token");
          this.validLogin = false;
        }
      });
    } else {
      console.log("Token Missing");
      this.validLogin = false;
    }

  }

当然,不要忘记在行中实现DoCheck

export class NavbarComponent implements OnInit, DoCheck

【讨论】:

    猜你喜欢
    • 2021-07-14
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 2019-04-25
    • 2020-08-27
    • 2021-05-07
    相关资源
    最近更新 更多