I’m collecting a lot of data from an API with an async function that cycles through a lot of data with a loop, I’m making about 100 requests and it takes around 8 seconds.
Are there any methods I can try to use, to speed up my script?
async function getplayerdata1() { // Get current room const response = await fetch(url) let teams = await response.json() let players = teams.players let playerarray = players.length for (var i = 0; i < playerarray; i++) { // console.log(players[i]); let username = players[i].username let userid = players[i].id // read user matches const usermatch = await fetch(`https://api.site.com/user_profile/get_latest_matches?_=&id=${userid}&page=1`) let matchlist = await usermatch.json() let matchlistarray = matchlist.length for (var ii = 0; ii < matchlistarray; ii++) { // console.log(matchlist[ii]) // Read match stats const matchlistResponse = await fetch(`https://api.site.com/match/get?_=&id=${matchlist[ii].id}`) let matchlistResponsestats = await matchlistResponse.json() // get 1st match stats async function matchdata() { if (matchlistResponsestats.players === null) { const kills = 0 const deaths = 0 const headshot = 0 const headshotproc = 0 return [kills, deaths, headshotproc, headshotproc] } else { const filterArray = matchlistResponsestats.players[i] console.log(filterArray) console.log(filterArray.kills) console.log(filterArray.deaths) console.log(filterArray.headshots) } } matchdata() } } } getplayerdata1() }
Advertisement
Answer
Instead of for
loops with await
inside, which runs in serial (each request must finish before the next beings), use Promise.all
instead, with .map
to map each item in an array to a Promise, which runs in parallel (every request runs as soon as it can, without waiting for other similar requests to finish first):
async function getplayerdata1() { // Get current room const response = await fetch(url); const { players } = await response.json(); return Promise.all(players.map(async (player, playerIndex) => { const { username, id } = player; // read user matches const response = await fetch(`https://api.site.com/user_profile/get_latest_matches?_=&id=${id}&page=1`); const matchlist = await response.json(); return Promise.all(matchlist.map(async ({ id }) => { // Read match stats const matchlistResponse = await fetch(`https://api.site.com/match/get?_=&id=${id}`); const matchlistResponsestats = await matchlistResponse.json(); // get 1st match stats if (matchlistResponsestats.players === null) { return [0, 0, 0, 0]; } else { const filterArray = matchlistResponsestats.players[playerIndex]; console.log(filterArray) console.log(filterArray.kills) console.log(filterArray.deaths) console.log(filterArray.headshots) } })); })); }
This will result in all possible requests going out at once. If the API / your connection can handle it, great – but if they can’t, you may need to throttle the requests.
Note that in most browsers, only around 6 requests will go at a time; if you make 100 requests at once, only ~6 of them may be active at once. Though, if the underlying protocol is http2, the requests can get multiplexed and sent across in a single go.