COIN LIST is an array of crypto coins(["BTCUSDT",...]). I try to get the price using getPriceAction and RSI from getRSI and these two functions are working when I try to console DATA. But when I try to print the response after the completion of the loop. It prints the empty array and the length is 0 of this array. I want to store the DATA object (consisting of SYMBOL, closing price and RSI) as an element in the response array
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();
If you want to use async/await properly for your code, then use async/await, don't use .then
/.catch
as well
Some notable changes
there is no setTimeout of increasing seconds ... just waiting 1 second after one result before getting the next - far cleaner, and if one request happens to take a lot longer, you won't end up with two requests at once (which may be an issue if the API is rate limited)
no .then
... use async
/await
OR .then
/.catch
- very rare to need both in the one function
don't use forEach with async
/await
... it never does what you want, and creating an array of Promises inside a .forEach
is extremely naive, you may as well use .map
instead! then you can await Promise.all(xxx.map(.....))
- but that's useful for concurrent requests, not so much for serial requests like your code does
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();
the await wait(1000)
could be tweaked depending on the rate limiting of the API ... if the rate limit applies to when the request is made, you could make a function that is smart about the delay between requests.
The code this way assumes the rate limit is based on the period between previous response to next request.