【问题标题】:Load data before component inialization - angular 2在组件初始化之前加载数据 - 角度 2
【发布时间】:2017-02-06 11:26:25
【问题描述】:

我的App.component 在我的user service 中调用了一个init 方法。

ngOnInit(){
    this.init(true).then(data => {
        console.log("OnInit Called")
    })     
}

User.service 返回一个promise,它又调用account.init

init = (isRegistered) => {
    return new Promise((resolve, reject) => {    
        this.account.init(isRegistered).then(data => {
            //some data inialization
            console.log("OnInit Called User Service")            
        });          
    });   
}

Account.service 返回一个使用Observable.forkJoin 调用多个服务的承诺

init = ((userType: boolean) => {
    return new Promise((resolve, reject) => {
         Observable.forkJoin([
             this.m1,
             this.m2]).subscribe(data => {
                 //persist those return data   
             });           
    });
}
  1. 为什么两个console.log 语句都不会被执行?
  2. 为什么在 Observable.forkJoin 完成其服务调用之前不阻止组件初始化?

【问题讨论】:

    标签: javascript angular typescript rxjs rxjs5


    【解决方案1】:
    1. (和 2.)呼叫 resolve(...) 不见了
    init = (isRegistered) => {
        return new Promise((resolve, reject) => {    
            this.account.init(isRegistered).then(data => {
                //some data inialization
                console.log("OnInit Called User Service")            
                resolve(/*someValue */); // <<<== missing
                // or reject(/* someValue */);
            });          
        });   
    }
    
    1. 您为什么希望它阻止任何内容? ngOnInit() 无法被阻止。例如,您可以使用*ngIf 在数据尚不可用之前不显示任何内容。 您还可以使用路由器防护来防止在数据可用之前创建组件。 https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard 但是在 JS 中没有办法以任何方式阻止执行。

    【讨论】:

    • 你一直都是对的,但实际上你可以进行同步服务器调用,所以有可能阻塞执行:) 没意义,但有可能
    • 好的,我认为它已被弃用,但如果这真的阻止了执行,仍然值得商榷。它只是占用了 UI 线程 - for 循环可以做同样的事情,但正如你所说 - 无论如何都毫无意义:D
    • :) for 循环可以阻止执行,但它永远无法接收异步调用的结果,因为它将被推送到事件队列。在收到异步响应之前阻止执行的唯一方法是 ES6 生成器或 async/await... 仍然毫无意义:D
    • 还有 generators 和 async/await 不阻塞,它们只是 .then( ...) 的语法糖,行为是一样的,只是代码可以写得更好。
    【解决方案2】:

    你肯定要先解决 Promise。

    init = (isRegistered) => {
        return new Promise((resolve, reject) => {    
            this.account.init(isRegistered).then(data => {
                // some data initialization
                if (data) {
                    resolve(...);
                } else {
                    reject(...);
                }
                console.log("OnInit Called User Service")            
            });          
        });   
    }
    

    很难说是什么问题,因为我们不知道this.m1this.m2 是什么。

    使用forkJoin() 时不要感到惊讶。如果该操作符forkJoin() 的源 Observable 之一失败或未发出任何值并过早完成,则该运算符不会发出任何值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-05
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多