代码之家  ›  专栏  ›  技术社区  ›  Greg Gum

为什么使用SetTimeout显示图表

  •  1
  • Greg Gum  · 技术社区  · 6 年前

    我有一个单页应用程序。

    在代码中,我获取数据,然后将其显示在图表中。

    但是,有一个时间问题:数据是在图表实例化之前获取的。所以图表最后什么也没有显示。

    我发现的解决方法是使用setTimeout()。但奇怪的是,我只设置了1毫秒的时间间隔,然后图表就正确显示了。

    我猜实际发生的是,通过使用setTimeout(),当前线程正在完成当前任务,然后返回到刷新函数,然后执行。对吗?

    有没有其他的方法我应该这样做,因为setTimeout()看起来很黑客,当然,我们不想这样做。

    这是获取数据的代码。

    async getItemStatusSummary(parentId:number) {
        this.logger.info("getItemStatusSummary()");
        this.itemStatusInfos = await this.statInfoService.getItemStatusInfoByFolderId(parentId, 'ALL');
        this.refreshItemStatusSummaryChart();
    }
    

    这是刷新:

    refreshItemStatusSummaryChart() {
    
        this.logger.info('RefreshingItemStatusSummaryChart()');
        const chart = $("#itemStatusSummaryChart").data("ejChart");
        if (chart) {
            chart.model.series[0].dataSource = this.itemStatusInfos;
            chart.animate(null);
        }
        else {
            this.logger.info('Chart is null');
            window.setTimeout(() => {
                this.refreshItemStatusSummaryChart();
            }, 1);
        }
    }
    
    3 回复  |  直到 6 年前
        1
  •  1
  •   benshabatnoam    6 年前

    你需要明白什么 setTimeout 在幕后做。

    关于这件事有一个很好的讨论 Philip Roberts 我的高度 建议你听,我马上在这里解释一下。

    javascript是一个单线程引擎,这意味着一次执行一个操作,这种类型的行为称为 堆栈 ,表示所有任务将按顺序执行。什么 设置超时 实际上正在做的是将传递给它的函数移到 任务队列 哪个在等 堆栈 清除所有任务。然后 事件循环 正在从 任务队列 把它传给 堆栈 再一次。

    这意味着打电话 设置超时 将在堆栈末尾执行您传递的函数,而不管您定义它等待的时间是什么,以及它为什么使用该值 0 .

    一个很好的解决方案,而不是使用 设置超时 将使用 ZONE.JS . 我不会在这个答案里回答的,而是检查这个 article 关于它。

        2
  •  1
  •   Sten Muchow    6 年前

    从事物的角度1.x的一面来看,这成为了一种被接受的方法/黑客,使事物能够正常工作,而这些东西是异步地相互妨碍的。

    在角中,只是强制另一个消化循环,所以添加到范围中的东西就会显示出来。在没有时间的情况下使用setTimeout是有效的,而且它更多的是在执行堆栈中显示它,而不是以任何方式延迟它。

    我希望这有帮助,这是一个奇怪的事情来处理,但在写了多年的Angular1.x应用程序后,我只是习惯了这种奇怪的Asycn行为来解决问题。

        3
  •  0
  •   Melchia    6 年前

    这不是你应该用的方法 setTimeout . 您需要返回 承诺 第一次行动 然后 执行第二个动作。

    async getItemStatusSummary(parentId:number) {
    
        this.logger.info("getItemStatusSummary()");
    
        this.statInfoService.getItemStatusInfoByFolderId(parentId, 'ALL')
                            .then ( response => {
                                    this.itemStatusInfos = response;
                                    this.refreshItemStatusSummaryChart();
                                   });
    
    }
    

    对于您,第二个操作/方法删除 设置超时 :

    refreshItemStatusSummaryChart() {
    
        this.logger.info('RefreshingItemStatusSummaryChart()');
        const chart = $("#itemStatusSummaryChart").data("ejChart");
        if (chart) {
            chart.model.series[0].dataSource = this.itemStatusInfos;
            chart.animate(null);
        }
        else {
            this.logger.info('Chart is null');
            this.refreshItemStatusSummaryChart();
        }
    }
    
    推荐文章