【发布时间】:2021-04-29 10:37:55
【问题描述】:
如何在 JavaScript 中等待函数完成?
我有 2 个函数 updateSeason 和 updateFixtures,我想等待第一个函数完成后再运行下一个函数。
我的两个函数都是异步的,它们工作得很好。唯一的问题是,如果我不使用setTimeout,我需要运行两次,因为updateFixture 在updateSeason 完成之前运行,并且在第一次运行时仍然没有要获取的文件。
更新数据
const updateData = async () => {
await updateSeason();
await updateFixtures();
};
更新季节
// 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...`);
});
};
更新夹具
// 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...");
});
};
更新:
问题在于函数本身。 async Array.prototype.map 在 updateSeason 和 updateFixtures 两个函数中都替换为 for 循环,现在正在工作
【问题讨论】:
-
leagues.map(async (league) =>这只是触发了一堆异步调用而不等待它们。使用传统的 for...of 循环。 stackoverflow.com/questions/37576685/…
标签: javascript asynchronous async-await