【问题标题】:How to make typescript execute code seqentially?如何使打字稿顺序执行代码?
【发布时间】:2019-01-13 14:43:25
【问题描述】:

我的代码似乎并没有等待执行某些代码并走得更远。

isAdmin(): boolean {
    this.getLoggedUser();
    this.getRole();
    console.log(this.admin);
    console.log('isAdmin');
    return this.admin;
  }

  getRole() {
    this.httpClient.get<boolean>('/api/has-role-admin').
    subscribe((data) => {
    this.admin = data;
    console.log(this.admin);
    console.log('getRole');
    }
    );
 }

控制台结果:

false
isAdmin
true
getRole

我想完成 getRole() 方法,然后在 isAdmin() 中完成该步骤。我怎么会收到这种行为?

【问题讨论】:

  • 不要subscribe。像这样的东西:stackoverflow.com/q/49444816/1132334
  • 另外,请记住 console.log 在某些浏览器中是异步的。
  • 感谢您的建议,这次 console.log 是正确的 :) 但是另一个问题是当我将 isAdmin() 创建为异步时,如何让它仍然返回布尔值?

标签: angular typescript


【解决方案1】:

您的代码是异步的,因为您订阅了一个 observable:

isAdmin(): boolean {
    this.getLoggedUser();
    this.getRole();
    console.log(this.admin);
    console.log('isAdmin');
    return this.admin;
  }

  getRole() {
    this.httpClient.get<boolean>('/api/has-role-admin').
    subscribe((data) => {
    ------------------------------------- This block will complete after the method returns
      this.admin = data;
      console.log(this.admin);
      console.log('getRole');
    }
    );
}

如果您的代码涉及可观察对象,则根据定义,它不能是顺序的。你需要重构你的方法以使用 observable 并且不依赖于 subscribe 方法的副作用。

我会以这种方式重构您的代码(我对您的代码做了几个假设,但总体思路应该成立):

public interface UserInfo{
    public isAdmin: boolean = false;
}

public getUserInfo(userId: integer): Observable<UserInfo> {
    let params = new HttpParams()
        .append('userId', userId.toString());

    return this.http.get<UserInfo>(this.baseUrl + "api/has-role-admin", { params: params });
}

public isAdminUser(userId: number): Observable<boolean>(){
    return this.getUserInfo(userId).pipe(map(x=> { return x.isAdmin; }));
}

并且服务器端 api 应该返回 UserInfo。您可以拨打isAdminUser(this.getLoggedUser().userId

【讨论】:

    【解决方案2】:

    这是在控制器中吗?名为 isAdmin 的方法可能不应该进行 HTTP 调用,尤其是当它被您的模板调用时,因为这样您最终会多次进行 HTTP 调用。

    相反,编写一个ngOnInit 进行调用并将结果存储到组件上的实例变量中。

    此外,HTTP 调用需要时间,并且您不应该在 Javascript 中阻塞线程。这样 HTTP 调用就会生成一个您订阅的 Observable。订阅会立即发生,但在 HTTP 响应到达之前不会执行回调。

    处理此问题的两种常见模式是使用ngIf 隐藏元素直到它被加载或使用async 管道。

    【讨论】:

      猜你喜欢
      • 2018-09-25
      • 2018-10-02
      • 1970-01-01
      • 2015-11-26
      • 2021-03-16
      • 2012-04-21
      • 1970-01-01
      • 2014-05-26
      相关资源
      最近更新 更多