我目前在给定页面上有大约14个以上的股票图表的环境中工作(每个图表都有20,0000+个唯一数据点,还有更多)。我有某些全局“切换”,例如,影响显示的系列,图表选项或极限轴(在所有图表上)。鉴于一次只能显示一个图表给用户,我想将更新图表视为一个队列,在该队列中,我先更新一个图表,然后再更新另一个,依此类推。
我的目标:依次循环调用Highcharts.Chart.redraw()(即,一次对页面中的每个图表调用redraw,以便首先重绘我的图表列表中的第一个图表)。请注意,图表列表的顺序是动态创建的,已经处理完毕。
到目前为止,我已经阅读了很多关于JavaScript Promise的信息,这些信息在过去用于链接Ajax调用。如以下链接所述:
我还在此处阅读了一些与循环中的Promises相关的一般问题:
我尝试了许多解决方案,并认为问题围绕使Highcharts重绘功能-或调用该功能的动作(如Chart.update(),Series.setVisible(),Axis.setExtremes())-返回承诺。
我已经上传了一个外壳here,它允许您触发一个事件,并且看到每个图表实际上都可以一次更新。
例如,如下所示:
$(Highcharts.charts).each(function(i, chart) {
console.log(i);
// decide what to do with the chart
// update Series, Chart options, Axis extremes... etc.
chart.redraw(); // call redraw at the end
})
将输出:
> 1, 2, 3, ..., n // pause, then charts would redraw()
可能很重要的一点是,尽管上面的内容似乎是响应式的,但在我的环境中,单击切换按钮和图表的重绘事件之间可能会有2-5秒的延迟。
我不知道要如何使循环等待每个图表完成其重绘,然后再进入列表中的下一个图表。 >
我们将不胜感激。
答案 0 :(得分:2)
如果我理解您的意思,则可以通过将触发器中的代码包装到setTimeout(超时值为0)中,然后包装在新的Promise中来实现
使用async / await就像
$('#trigger').click(async (e) => {
for (let chart of Highcharts.charts) {
await new Promise(resolve => setTimeout(() => {
chart.series.forEach(series => series.setVisible(undefined, false));
chart.redraw();
resolve();
}, 0));
}
});
答案 1 :(得分:1)
通用解决方案
通常,如果您要按顺序依次链接诺言,可以使用以下格式
function promiseChain(i) {
return new Promise(resolve => {
/* DO ASYNC STUFF */
// Resolve with some result if the next item in the chain needs it
return resolve("OK");
});
}
let p = Promise.resolve(null);
for (let i = 0; i < 5; i++) {
p = p.then(prevResult => {
if (prevResult) {
// Do stuff with prevResult if needed
}
// Chain next item
return promiseChain(i);
});
}
带有日志的示例
这将记录数字0-4,一次记录一次,每次之间等待一秒钟。
function promiseChain(i) {
return new Promise(resolve => {
setTimeout(() => {
console.log(i);
return resolve("OK");
}, 1000)
});
}
let p = Promise.resolve(null);
for (let i = 0; i < 5; i++) {
p = p.then(prevResult => {
if (prevResult) {
// Do stuff with prevResult if needed
}
return promiseChain(i);
});
}