Reputation: 155
How to wait for function to finish in JavaScript?
I have 2 functions updateSeason
and updateFixtures
and I want to wait for first one to finish before run next one.
Both my functions are async and they working perfectly fine. Only problem is if I do not use setTimeout
I need to run it twice because updateFixture
run before updateSeason
finish and there is still no file for fucntion to fetch on first run.
updateData
const updateData = async () => {
await updateSeason();
await updateFixtures();
};
updateSeason
// UPDATE SEASON
const updateSeason = async () => {
// SEASONS TEMPLATE
let seasonsTemplate = {
timestamp: new Date(),
season: null,
leagues: [],
};
// FETCH LEAGUES INFO
const leagues = await fetch(url + "leagues?subscribed=true&" + key)
.then((response) => response.json())
.then((data) => data.data);
// MAP THROUGH LEAGUES
leagues.map(async (league) => {
const id = `${league.league_id}&`;
// FETCH SEASONS INFO
const seasons = await fetch(url + "seasons?league_id=" + id + key)
.then((response) => response.json())
.then((data) => data.data);
// MAP THROUGH LEAGUES & POPULATE SEASONS TEMPLATE
seasons.map((season) => {
if (season.is_current) {
seasonsTemplate.season = `${moment(season.start_date).format("YYYY")}_${moment(season.end_date).format("YYYY")}`;
seasonsTemplate.leagues.push({
country_id: season.country_id,
league_id: league.league_id,
league_name: league.name,
season_id: season.season_id,
start_date: season.start_date,
end_date: season.end_date,
});
}
});
// CHECK / CREATE SEASON FOLDER
const currentSeasonFolder = `./data/${seasonsTemplate.season}`;
if (!existsSync(currentSeasonFolder)) {
await mkdir(currentSeasonFolder);
await mkdir(`${currentSeasonFolder}/matches`);
}
// CREATE / UPDATE SEASON FILES
await writeFile("./data/current_season.json", JSON.stringify(seasonsTemplate));
await writeFile(`${currentSeasonFolder}/season.json`, JSON.stringify(seasonsTemplate));
console.log(`${league.name} updated...`);
});
};
updateFixtures
// UPDATE FIXTURES
const updateFixtures = async () => {
// FIXTURES TEMPLATE
let fixturesTemplate = {
timestamp: new Date(),
season: null,
fixtures: [],
};
// FETCH CURRENT SEASON INFO
const season = await fetch(api + "current_season.json").then((response) => response.json());
// POPULATE FIXTURES TEMPLATE SEASON
fixturesTemplate.season = season.season;
// MAP THROUGH LEAGUES
season.leagues.map(async (league) => {
const id = `${league.season_id}&`;
// FETCH COMPETITION FIXTURES
const fixtures = await fetch(url + "matches?season_id=" + id + key)
.then((response) => response.json())
.then((data) => data.data);
// MAP THROUGH FIXTURES & POPULATE FIXTURES TEMPLATE
fixtures.map((match) => {
if ((match.home_team.team_id === teamId || match.away_team.team_id === teamId) && match.status !== "postponed") {
fixturesTemplate.fixtures.push({
match_timestamp: new Date(match.match_start_iso).getTime(),
match_start: match.match_start_iso,
match_id: match.match_id,
status: match.status === "" ? "notstarted" : match.status,
home_team: getTeamName(match.home_team.team_id),
home_short: getShortName(match.home_team.team_id),
away_team: getTeamName(match.away_team.team_id),
away_short: getShortName(match.away_team.team_id),
});
}
});
// SORT FIXTURES BY DATE IN ASCENDING ORDER
fixturesTemplate.fixtures.sort((a, b) => a.match_timestamp - b.match_timestamp);
// CREATE / UPDATE FIXTURES FILES
const currentSeasonFolder = `./data/${season.season}`;
await writeFile(currentSeasonFolder + "/fixtures.json", JSON.stringify(fixturesTemplate));
console.log("Fixtures updated...");
});
};
UPDATE:
Issue was inside functions itself. async Array.prototype.map
repleaced with for
loop in both functions updateSeason
and updateFixtures
and now is working
Upvotes: 4
Views: 15569
Reputation: 92
You can just use async/await for your defined functions, even if you cannot use 'await' keyword outside an async function.
So, for example, you have a index.js file, you can do:
async function main() {
await updateSeason();
await updateFixtures();
}
main()
or invoking directly the function with the short form
(async function main() {
await updateSeason();
await updateFixtures();
})()
Anyway, avoid to use 'writeFileSync' or other 'Sync' functions inside an async function because that block the event loop and decrease your performance.
EDIT: I saw now that you are using Array.prototype.map function with an async callback, that could be the problem.
Try to look here: https://flaviocopes.com/javascript-async-await-array-map/
Or, otherwise, use a standard for loop to handle your leagues
Upvotes: 2
Reputation: 755
You forgot to put "await" before the function
const updateData = async () => {
// Add await before the functions because they are async functions
await updateSeason()
await updateFixtures()
};
Upvotes: 0
Reputation: 51
Async Await can help you out here since they are both async functions.
const updateData = async () => {
await updateSeason();
await updateFixtures();
};
Upvotes: 0
Reputation: 6996
Why not just,
async function updateData() {
await updatedSeason();
await updateFixtures()
}
updateData();
Upvotes: 1