var https = require("https"); const arr = []; for (let i = 1; i < 26; i++) { https.get( `https://jsonmock.hackerrank.com/api/countries?page=${i}`, (res) => { res.on("data", (data) => { JSON.parse(data).data.map((info, i) => { let { name } = info; arr.push(name); console.log(name); }); }); } ); } console.log(arr);cuando solo registro JSON. parse (datos), obtengo los datos requeridos en mi consola
pero cuando trato de insertarlo en una matriz, no sucede, sino que registra una matriz vacía en la consola
Realmente necesito saber el motivo, ya que estoy atascado con esto durante 3 días.
Su problema es que la devolución de llamada a https.get , es decir, (res) => se llama de forma asincrónica , por lo tanto, console.log(arr); se ejecuta antes de que se realicen las 25 solicitudes https.get ; verá que arr.push realmente funciona si console.log(arr); donde console.log(name); - por lo que su suposición de que no puede empujar es incorrecta
Está empujando a la matriz, simplemente nunca consola. Registre la matriz cuando tenga datos.
Supongo que una forma en que puedo sugerir hacer esto con la versión bastante antigua de Node.js que está usando (14.16.0) es la siguiente
var https = require("https"); function fn(callback) { const result = []; let done = 0; for (let i = 1; i < 26; i++) { https.get(`https://jsonmock.hackerrank.com/api/countries?page=${i}`, (res) => { res.on("data", (data) => { JSON.parse(data).data.map((info) => { let { name } = info; result.push(name); console.log(name); }); // keep track of how many requests have "completed" done = done + 1; // when all are done, call the callback if (done === 25) { callback(result); } }); }); } } fn(arr => { // here is where arr is populated, nowhere else console.log(arr); }); Tenga en cuenta que solo se podrá acceder a arr dentro de la devolución de llamada; NO podrá acceder a arr en el nivel superior como desea; la única forma posible de hacerlo es usar una versión de Node.js que admita la await de nivel superior: y convierta el código para usar Promise (que es una tarea trivial)
No estoy seguro de que sea importante, pero no hay garantía de que los nombres en arr estén en el orden correcto... es decir, los resultados de la iteración 3 pueden enviarse después de la iteración 4, por ejemplo, dado que esa es la naturaleza de las solicitudes de red, no hay garantizo cuando van a terminar
Como un aparte. Si tuviera que usar la versión más reciente (18.1 en el momento de escribir este artículo) de node.js, lo anterior se puede escribir como
const promises = Array.from({length:25}, async (_, i) => { const res = await fetch(`https://jsonmock.hackerrank.com/api/countries?page=${i+1}`); const data = await res.json(); return data.map(({name}) => name); }); const arr = (await Promise.all(promises)).flat(2); console.log(arr);Las cosas a destacar son
fetch nativa: lo que hace que las solicitudes de redes sean simples en comparación con los métodos regulares de node.jsawait de nivel superior: por lo tanto, puede usar arr en el nivel superior del código