您好,感谢您花时间阅读我的问题。
我有一个 Vue 组件,称之为“interactiveChart”。在安装时(按如下所示的特定顺序),我执行以下操作:
初始化我的东西(数据库管理器、工具管理器等)
第一次调用 this.run(); 获取我的数据。 [this.run(); 调用 this.fetch(); 返回一个 Promise< /em>,根据我在highchart中对我的数据进行排序,将数据按顺序排列等等。我只是处理逻辑。所以是这样的:
到目前为止一切顺利。所以,我们仍然处于挂载状态,在初始化和第一次调用 this.run() 之后,我在那里有一些事件处理程序(它们工作正常),它们侦听特定事件。在事件侦听器之后,我再次运行 this.render(),因为某些事件可能会更改图表选项(添加另一个轴等)。 但是。我们最初解析的数据基于特定的 id。假设 id 1。有些事件可能会要求另一个 id 的数据,比如说 2,3 和 4。这意味着我必须再次运行 this.run() 以获取 2,3 和 4。所以不要运行它.run() 仅用于一个 id,我使用一个名为 idNotations 的数组来存储解析数据所需的所有 id。我在 this.run() 中做了一个 for of 循环来获取每个 id 的数据。我的问题如下:
如果我给出 4 个 id,this.run() 中的 this.render() 函数将运行 4 次(所以我一直看到图表重新加载 1-2 秒)然后它正确显示。数据显示得很好。它只是在为每个 ID 获取所有数据之前渲染运行。我想要的是让它只运行一次,在所有的承诺都完成之后。如果我将 render() 移到 for of 循环之外,它就不会显示(因为 run() 不是异步的,它只是调用 fetch 以避免代码重复。我该如何解决这个问题?
mounted() {
console.log('Function Call: mounted()');
//Initialization
this.selectedTimeSpan = timeSpansArray.find((el) => el.timeSpan == '5Y');
this.mdg2Client = globalMdg2ClientFactory.createMdg2Client();
this.highchartOptions = this.getHighchartsOptions();
this.run();
/**
* Events Below
*/
//When Timespan Changes
this.$root.$on('chartZoom', (payload) => {
console.log('[Event Emitted] - Timespan Changed');
this.interactiveChart.showLoading('Loading Data..');
this.selectedTimeSpan = timeSpansArray.find(
(el) => el.timeSpan === payload.timeSpan
);
this.run();
});
//When Chart Type Changes
this.$root.$on('chart-type', (payload) => {
console.log('[Event Emitted] - Chart Type/Data Changed', payload);
//Reseting step
this.hasStep = false;
//Need yMin in OHLC and Candlestick chart types
let yMin = toolsManager.calculateMin(
this.highchartOptions.series[0].data
);
//Swap between chart types
switch (payload['chart-type']) {
case 'step':
this.hasStep = true;
case 'mountain':
this.highchartOptions.series[0].type = null;
this.highchartOptions.chart.type = 'area';
this.highchartOptions.yAxis[0].min = yMin;
break;
case 'candlestick':
this.highchartOptions.series[0].type = 'candlestick';
break;
case 'ohlc':
this.highchartOptions.series[0].type = 'ohlc';
break;
default:
this.highchartOptions.series[0].type = 'line';
break;
}
this.highchartOptions.series[0].step = this.hasStep;
//Select performance
if (payload['chart-perf'] === 'axisTrue') {
this.highchartOptions.plotOptions.series.compare = 'percent';
this.highchartOptions.yAxis[0].min = null;
this.highchartOptions.yAxis[0].labels.format = '{value:.2f}%';
} else {
this.highchartOptions.plotOptions.series.compare = null;
this.highchartOptions.yAxis[0].labels.format = null;
}
//Benchmark selected
if (payload['add-benchmark']) {
if (payload['add-benchmark'].length > 0) {
this.interactiveChart.showLoading('Loading Data..');
this.benchmarks = payload['add-benchmark'];
this.cleanIds();
this.renderFlag = false;
this.run();
this.renderFlag = true;
} else {
this.cleanSeries();
this.cleanBenchmarks();
this.cleanIds();
}
}
//Indicators selected
if (payload['indicators']) {
if (payload['indicators'].length > 0) {
this.interactiveChart.showLoading('Loading Data..');
this.indicators = payload['indicators'];
this.sortIndicators();
} else {
while (this.indicators.length > 0) {
this.indicators.pop();
}
this.cleanIndicators();
}
}
this.render(this.highchartOptions);
});
//Fetching Data from server
fetch(timeSpan, idToFetchFrom) {
console.log(`Function Call: fetch()`);
this.timespanDates = toolsManager.calculateDates(
timeSpan.totalTimeRange.days
);
const data = {
id: idToFetchFrom,
quality: this.priceQuality,
range: {
start: this.timespanDates[0],
end: this.timespanDates[1],
},
};
const meta = {
pagination: {
limit: timeSpan.totalTimeRange.days,
},
};
//If it is 1D or 5D
if (this.selectedTimeSpan.getIntradayData) {
data.type = 'trade';
data.quality = 'DLY';
data.range.start.concat('T00:00:00.000Z');
data.range.end.concat('T07:00:00.000Z');
data.granularity = timeSpan.granularity;
timeSpan.timeSpan === '1D'
? (meta.pagination.limit *= 24 * 60) //Days * 24 Hours * 60 (1 minute granularity so 60*1M===1H)
: (meta.pagination.limit *= 24 * 6); //Days * 24 Hours * 6 (10 minutes granularity so 6*10M===1H)
return this.mdg2Client.requestEndpoint(
this.requestMethod,
'/api/v1/prices/timeSeries/intraday/subsample/list',
{ data, meta }
);
} else {
return this.mdg2Client.requestEndpoint(
this.requestMethod,
this.endpoint,
{ data, meta }
);
}
},
//Handling the response from the server
run() {
console.log('Function Call: run()');
this.sortIndicators();
for (let id of this.idsToFetchData) {
console.log(`run(): ${id}`);
this.fetch(this.selectedTimeSpan, id)
.then((res) => {
const { data } = res;
let prices = [];
//we get an array subsamples when we use the endpoint for 1D and 5D, but an array called prices for the rest of the timespans
this.selectedTimeSpan.getIntradayData
? (prices = data.subsamples)
: (prices = data.prices);
let priceSeries = [];
this.volumeSeries = [];
/**
* Tick Interval can be either 1 or 5. We get the lowest price each day or every fifth one.
*/
if (this.selectedTimeSpan.tickInterval === 1) {
for (let i = 0; i < prices.length; i++) {
let xData = null;
this.selectedTimeSpan.getIntradayData
? (xData = Math.floor(new Date(prices[i].time).getTime()))
: (xData = Math.floor(new Date(prices[i].date).getTime()));
priceSeries[i] = {
x: xData,
open: prices[i].first,
high: prices[i].high,
low: prices[i].low,
close: prices[i].last,
y: prices[i].last,
volume: prices[i].tradingVolume,
};
if (id == this.$props.idNotation) {
this.volumeSeries[i] = {
x: xData,
y: prices[i].tradingVolume,
};
}
}
} else {
let j = 0;
for (
let i = 4;
i < prices.length;
i += this.selectedTimeSpan.tickInterval
) {
priceSeries[j] = {
x: Math.floor(new Date(prices[i].date).getTime()),
open: prices[i].first,
high: prices[i].high,
low: prices[i].low,
close: prices[i].last,
y: prices[i].last,
volume: prices[i].tradingVolume,
};
if (id == this.$props.idNotation) {
this.volumeSeries[j] = {
x: Math.floor(new Date(prices[i].date).getTime()),
y: prices[i].tradingVolume,
};
}
j++;
}
}
if (id == this.$props.idNotation) {
this.highchartOptions.series[0].data = priceSeries;
this.highchartOptions.series[1].data = this.volumeSeries;
} else {
this.benchmarks.forEach((benchmark) => {
if (benchmark.id == id) {
benchmark.data = priceSeries;
this.highchartOptions.series.push(benchmark);
}
});
}
// this.sortIndicators(this.indicators);
this.highchartOptions.xAxis.labels.format = `{value:${this.selectedTimeSpan.xAxisDateFormat}}`;
console.log('look', this.renderFlag);
if (this.renderFlag) this.render(this.highchartOptions);
})
.catch((e) => {
console.log('[ Caught Error ]', e);
});
}
},
答案 0 :(得分:0)
按照 recoilnetworks 的建议使用 Promise.all() 解决。谢谢!