Como alguien que todavía es muy nuevo en JS, me cuesta entender por qué algunas de las funciones y el código que escribo dan resultados inconsistentes dentro de la consola. Por ejemplo, la salida de una matriz contendrá 4 elementos en una actualización de la página web, luego contendrá 8 elementos en la próxima actualización. ¿Por qué podría suceder esto?
Ejemplo de esto:
function biggestChanges(idsList) { var listOfChanges = [] for (let i = 0; i < 16; i++) { fetch(`jsonFiles\\${idsList[i]}.json`) .then(response => response.json()) .then(data => { //get data from JSON file var priceCurrentNEW = data.JSONdata[data.JSONdata.length - 1].prices[0] var priceDayBeforeNEW = data.JSONdata[data.JSONdata.length - 2].prices[0] var priceCurrentUSED = data.JSONdata[data.JSONdata.length - 1].prices[1] var priceDayBeforeUSED = data.JSONdata[data.JSONdata.length - 2].prices[1] var changeNEW = priceCurrentNEW / priceDayBeforeNEW * 100 -100 var changeUSED = priceCurrentUSED / priceDayBeforeUSED * 100 - 100 var averageChange = (changeNEW + changeUSED) / 2 averageChange = averageChange.toFixed(2) subList = [idsList[i], averageChange] listOfChanges.push(subList) //run on last iteration. if (i == 15) { var orderedList = [] var originalLength = listOfChanges.length for (var x = 0; x < 16; x++) { var max = listOfChanges[0][1] var index = 0 // -k on range as on each iteration the length of the list decreases by 1 for (var k = 0; k < 16-k; k++) { if (listOfChanges[k][1] > max) { max = listOfChanges[k][1] index = k } } orderedList.push(listOfChanges[index]) listOfChanges.splice(index, 1) } console.log(orderedList, "orderedlist") for (var l = 0; l < orderedList.length; l++){ document.getElementById(`change-${orderedList[l][0]}`).innerHTML = "change: £" + orderedList[l][1] } } }) } } function finalBiggestChanges() { fetch("JSONitemIDsList.json") .then(response => response.json()) .then(data => { biggestChanges(data.ids) }) } finalBiggestChanges()Tienes una condición de carrera. //run on last iteration. en realidad se ejecuta durante la devolución de llamada de la última iteración para iniciar la llamada fetch(`jsonFiles\\${idsList[i]}.json`) , pero no necesariamente cuando llegó la última respuesta http.
Puede mitigar esto haciendo if (listOfChanges.length == 16) (es decir, cuando se agregó la respuesta número 16 a la matriz) en lugar de if (i == 15) , pero en realidad la solución adecuada es usar Promise.all en su lugar:
function loadChange(id) { return fetch(`jsonFiles\\${idsList[i]}.json`) .then(response => response.json()) .then(data => { //get data from JSON file var priceCurrentNEW = data.JSONdata[data.JSONdata.length - 1].prices[0] var priceDayBeforeNEW = data.JSONdata[data.JSONdata.length - 2].prices[0] var priceCurrentUSED = data.JSONdata[data.JSONdata.length - 1].prices[1] var priceDayBeforeUSED = data.JSONdata[data.JSONdata.length - 2].prices[1] var changeNEW = priceCurrentNEW / priceDayBeforeNEW * 100 -100 var changeUSED = priceCurrentUSED / priceDayBeforeUSED * 100 - 100 var averageChange = (changeNEW + changeUSED) / 2 averageChange = averageChange.toFixed(2) return [id, averageChange] }); } function finalBiggestChanges() { return fetch("JSONitemIDsList.json") .then(response => response.json()) .then(data => { return Promise.all(data.ids.slice(0, 16).map(loadChange)); }) .then(listOfChanges => { listOfChanges.sort((a, b) => b[1] - a[1]); // largest first console.log(listOfChanges, "orderedlist") for (const change of listOfChanges) { document.getElementById(`change-${change[0]}`).innerHTML = "change: £" + change[1] } }); } finalBiggestChanges().catch(console.error);