У меня проблемы с пониманием того, как обойти асинхронное поведение Javascript в цикле forEach. Эта проблема довольно сложна (извините), но идея цикла следующая:
- Цикл каждого элемента в массиве
- Сделать HTTP-запрос из скрипта провайдера
- Затем мне нужно умножить каждый элемент массива на постоянную
- Назначение нового массива элементу в объекте
- После цикла возьмите все массивы и сложите их в один массив
Данные будут присвоены массиву indvCoinPortfolioChartData
Я ищу любые недостатки в цикле событий. Я считаю, что битва делает эту задачу синхронной, проверяя, назначены ли мои данные перед агрегацией данных.
выпуск
Когда я добавляю все массивы вместе, ОДИН набор данных не суммируется (я думаю, потому что он все еще обрабатывается после вызова функции). Нет ошибки, но в ней нет всех данных о монетах в окончательном агрегированном массиве.
Это проблема, которую я вижу в функции aggregatePortfolioChartData. Он начинает цикл for только с двумя элементами в массиве, а затем показывает 3. Третий элемент не был обработан до тех пор, пока не начался цикл for.
образ журнала консоли (записывается с помощью функции aggregatePortfolioChartData)
журнал отладки при успешной агрегации
var indivCoinPortfolioChartData = {'data': []};
for(var i = 0; i < this.storedCoins.Coins.length; i++)
{
let entry = this.storedCoins.Coins[i];
localThis._data.getChart(entry.symbol, true).subscribe(res => {localThis.generateCoinWatchlistGraph(res, entry);});
localThis._data.getChart(entry.symbol).subscribe(res => {
if(entry.holdings > 0)
{
let data = res['Data'].map((a) => (a.close * entry.holdings));
indivCoinPortfolioChartData.data.push({'coinData': data});
localThis.loadedCoinData(loader, indivCoinPortfolioChartData);
}
else
{
localThis.loadedCoinData(loader, indivCoinPortfolioChartData);
}
});
}
Данные загруженной монеты
loadedCoinData(loader, indivCoinPortfolioChartData)
{
this.coinsWithData++;
if(this.coinsWithData === this.storedCoins.Coins.length - 1)
{
loader.dismiss();
this.aggregatePortfolioChartData(indivCoinPortfolioChartData);
}
}
aggregatePortfolioChartData
aggregatePortfolioChartData(indivCoinPortfolioChartData)
{
console.log(indivCoinPortfolioChartData);
var aggregatedPortfolioData = [];
if(indivCoinPortfolioChartData.data[0].coinData)
{
let dataProcessed = 0;
for(var i = 0; i < indivCoinPortfolioChartData.data[0].coinData.length; i++)
{
for(var j = 0; j< indivCoinPortfolioChartData.data.length; j++)
{
let data = indivCoinPortfolioChartData.data[j].coinData[i];
if(data)
{
aggregatedPortfolioData[i] = (aggregatedPortfolioData[i] ? aggregatedPortfolioData[i] : 0) + data;
dataProcessed++;
}
else
{
dataProcessed++;
}
}
if(dataProcessed === (indivCoinPortfolioChartData.data[0].coinData.length) * (indivCoinPortfolioChartData.data.length))
{
console.log(dataProcessed + " data points for portfolio chart");
this.displayPortfolioChart(aggregatedPortfolioData);
}
}
}
}
Спасибо за помощь в решении этой утомительной проблемы.