我有一个单页应用程序。
在代码中,我获取数据,然后将其显示在图表中。
但是,存在计时问题:图表实例化之前就已获取数据。因此,图表最终没有显示任何内容。
我发现的解决方法是使用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);
}
}
答案 0 :(得分:1)
从事物的Angular 1.x方面来看,这已成为一种公认的方式/技巧,它可以使彼此不同步的事物正常工作。
在angular中,仅强制执行另一个摘要循环,因此添加到示波器中的东西将显示出来。使用没有时间的setTimeout可以正常工作,而更多的是将其显示在执行堆栈的下方,而不是以任何方式实际延迟它。
我希望这会有所帮助,这是一件奇怪的事情,但是经过多年编写有角度的1.x应用程序后,我才习惯于这种奇怪的asycn行为来解决问题。
答案 1 :(得分:1)
您需要了解setTimeout
在幕后所做的事情。
Philip Roberts对此有很好的论述,我对此高度评价 建议您听,我会在这里尽快解释。
JavaScript是一个单线程引擎,这意味着一次执行一个动作,这种行为称为 stack ,这意味着所有任务将按顺序执行。 setTimeout
实际在做什么,就是将您的函数传递给它,并将其移到任务队列中,该队列正等待堆栈清除所有任务。然后,事件循环将从任务队列中获取您的功能,然后再次将其传递给堆栈。
这意味着调用setTimeout
将在堆栈的末尾执行传递的函数,而不管您定义等待的时间如何,以及为什么它使用值0
。
对于您来说,一个很棒的解决方案是使用 Zone.js ,而不是使用setTimeout
。
在本答案中,我将不作介绍,而应对此问题进行检查article。
答案 2 :(得分:0)
这不是您应该使用setTimeout
的方式。您需要先返回承诺,然后执行 第二步。
async getItemStatusSummary(parentId:number) {
this.logger.info("getItemStatusSummary()");
this.statInfoService.getItemStatusInfoByFolderId(parentId, 'ALL')
.then ( response => {
this.itemStatusInfos = response;
this.refreshItemStatusSummaryChart();
});
}
关于您的第二项操作/方法,请删除setTimeout
:
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();
}
}