LISTA DE MONEDAS es una matriz de monedas criptográficas (["BTCUSDT",...]). Intento obtener el precio usando getPriceAction y RSI de getRSI y estas dos funciones funcionan cuando intento consolar DATA. Pero cuando trato de imprimir la respuesta después de completar el ciclo. Imprime la matriz vacía y la longitud es 0 de esta matriz. Quiero almacenar el objeto DATA (que consta de SÍMBOLO, precio de cierre y RSI) como un elemento en la matriz de respuesta
import { COIN_LIST } from "./COIN_LIST.js"; import { getPriceAction } from "./PRICE_ACTION.js"; import { getRSI } from "./RSI.js"; async function main() { try { let response = await []; await COIN_LIST.forEach((element, i) => { setTimeout(() => { let data = { symbol: element }; getPriceAction(element, "4h").then((res) => { data.closingPrice = res; getRSI(res).then((res) => { data.RSI = res.reverse(); data.closingPrice = data.closingPrice.reverse(); response.push(data); console.log(data) }); }); }, i * 1000); }); console.log(response); } catch (error) { console.log(error.message); } } main();Si desea usar async/await correctamente para su código, use async/await, no use .then / .catch también
Algunos cambios notables
no hay setTimeout de aumento de segundos... simplemente espera 1 segundo después de un resultado antes de obtener el siguiente, mucho más limpio, y si una solicitud toma mucho más tiempo, no terminará con dos solicitudes a la vez (lo que puede ser un problema si la API tiene una tasa limitada)
no .then ... use async / await OR .then / .catch - muy raro necesitar ambos en una función
no use forEach con async / await ... nunca hace lo que quiere, y crear una matriz de Promises dentro de .forEach es extremadamente ingenuo, ¡también puede usar .map en su lugar! entonces puede await Promise.all(xxx.map(.....)) - pero eso es útil para solicitudes concurrentes, no tanto para solicitudes en serie como lo hace su código
import { COIN_LIST } from "./COIN_LIST.js"; import { getPriceAction } from "./PRICE_ACTION.js"; import { getRSI } from "./RSI.js"; async function main() { try { const wait = (ms) => new Promise(resolve => setTimeout(resolve, 1000)); let response = []; //---> don't need that `await` for (let element of COIN_LIST) { let data = { symbol: element }; data.closingPrice = await getPriceAction(element, "4h"); const res = await getRSI(data.closingPrice); data.RSI = res.reverse(); data.closingPrice = data.closingPrice.reverse(); response.push(data); console.log(data); await wait(1000); } console.log(response); } catch (error) { console.log(error.message); } } main(); la await wait(1000) podría modificarse según el límite de velocidad de la API ... si el límite de velocidad se aplica cuando se realiza la solicitud, podría hacer una función que sea inteligente sobre el retraso entre las solicitudes.
El código de esta manera asume que el límite de velocidad se basa en el período entre la respuesta anterior y la siguiente solicitud.
Después de completar el ciclo, las promesas aún no se resolvieron, es por eso que imprime una matriz vacía. Una forma de lograr lo que necesita es usar await for(...) , o esperar a que se resuelvan todas las promesas, y luego imprimir los resultados.
import { COIN_LIST } from "./COIN_LIST.js"; import { getPriceAction } from "./PRICE_ACTION.js"; import { getRSI } from "./RSI.js"; async function main() { try { let response = []; //---> don't need that `await` const promises = []; //---> array of promises COIN_LIST.forEach((element, i) => { setTimeout(() => { let data = { symbol: element }; const promise = getPriceAction(element, "4h").then((res) => { data.closingPrice = res; getRSI(res).then((res) => { data.RSI = res.reverse(); data.closingPrice = data.closingPrice.reverse(); response.push(data); console.log(data) }); }); promises.push(promise) //---> save the reference to a promise }, i * 1000); }); await Promise.all(promises) //---> await for all promises to be resolved, then print the result console.log(response); } catch (error) { console.log(error.message); } } main();