Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait for function to finish in javascript?

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

like image 492
Klak031 Avatar asked Aug 31 '25 20:08

Klak031


2 Answers

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

like image 53
Kira Avatar answered Sep 03 '25 14:09

Kira


Why not just,

async function updateData() {
  await updatedSeason();
  await updateFixtures()
}

updateData();
like image 21
painotpi Avatar answered Sep 03 '25 12:09

painotpi