【问题标题】:Synchronous Angular 8 HTTP request from a service来自服务的同步 Angular 8 HTTP 请求
【发布时间】:2019-08-05 00:16:05
【问题描述】:

我正在尝试使用来自 Angular 8 服务的 http GET 请求。我需要通过 RESTful 服务加载一些数据,然后使用它们来填充 D3 图(D3 端不是问题)。

我正在尝试使用 async/await 功能。

在 ngOnInit 中,我尝试使用 HTTP 请求加载数据,如下所示:

ngOnInit() { 
  console.log("ngOnInit");
  this.loadRESTDataSync();
}

async loadRESTDataSync() {    
  console.log("PRE-REST!")
  this.m_graph = await this.loadRESTDataPromise(); 
  console.log("POST-REST!");
  //works on m_graph...
}

private loadRESTDataPromise(): Promise<any> {
    return this.service.getData().toPromise()
      .then(resp => resp as MyObjects[]);
}

然后我尝试在 ngAfterViewInit 中创建 D3 图表,如下所示:

ngAfterViewInit() {
  console.log("ngAfterViewInit");
  this.createChart();
}

控制台打印的顺序是:

ngOnInit
PRE_REST!
ngAfterViewInit
POST-REST!

所以,当我运行应用程序时,图表是空的,因为在 http rest 调用终止之前调用了 ngAfterViewInit(因此还没有要显示的数据)。

应该在 loadRestDataSync/loadRESTDataPromise 终止之后调用 ngAfterViewInit。

执行此操作的正确方法是什么?也许我对循环挂钩的看法有误?

我实现了 onResize 方法,如果我调整窗口大小,图形是正确的,但问题是第一次加载。

你能给我一些正确的方法吗?

非常感谢,再见。

【问题讨论】:

    标签: angular rest http d3.js service


    【解决方案1】:

    loadRESTDataSync() 是异步的,所以它不会阻塞 ui 线程,所以ngAfterViewInit() 可以随意发生。明智的做法是不要像您注意到的那样阻止 ui 线程进行数据获取。现在您只需要在this.m_graph = await this.loadRESTDataPromise(); 之后调用createChart()

    我有同样的问题,在可能的情况下,我更愿意提出“获取完整消息”并对这个事件做出反应:

    dataIsLoaded = new Subject<any>();
    
    ngOnInit() {
         this.dataIsLoaded.subscribe(d => this.createChart(d));
         this.loadRESTDataSync();
    }
    
    async loadRESTDataSync() {    
      this.m_graph = await this.loadRESTDataPromise();
      //works on m_graph...
      this.dataIsLoaded.next(d);
    }
    
    this.createChart(data) {
      //
    }
    

    您可以将数据存储在一个变量中,当您的数据准备好时,只需发出一条空消息来通知订阅的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-19
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      相关资源
      最近更新 更多