[英]How can I combine these two async functions?
我正在通過一個團隊數組循環獲取每個團隊的團隊數據和球員......
我有 2 個異步函數可以提取相同的數據,但我不知道如何組合它們。
由於它目前有效,每個循環將 teamPlayers 數組添加到第一個異步 function 中的玩家數組中。 完成后,我的玩家數組中有 1450 個玩家對象。 第二個異步 function 將團隊 object 添加到團隊數組中。 完成后,我的團隊數組中有 32 個團隊對象。
我嘗試更改第一個異步 function 以獲取數據,然后讓調度返回 results.teamPlayers 的值,但我最終得到了一個包含 32 個 arrays 的玩家數組,每個數組都有 x 個玩家對象。
async function loadRosters(endPoints, teams, authKey) {
axios.defaults.headers.common['Authorization'] = authKey;
const requests = teams.map(teamId => {
try {
return axios.get(endPoints.roster + teamId).then(r => r.data.teamPlayers);
} catch (e) {
console.log(e);
}
return [];
});
const results = (await Promise.all(requests)).flat();
dispatch({ type: 'SET_PLAYERS', value: results });
return results;
}
async function loadTeamData(endPoints, teams, authKey) {
axios.defaults.headers.common['Authorization'] = authKey;
const requests = teams.map(teamId => {
try {
return axios.get(endPoints.roster + teamId).then(r => r.data.team);
} catch (e) {
//
}
return [];
});
const results = (await Promise.all(requests)).flat();
dispatch({ type: 'SET_TEAM_LOGOS', value: results });
return results;
}
這是我得到的數據的結構:
{
"team": {
"teamId": "string",
"abbr": "string",
"logo": "string"
},
"teamPlayers": [
{
"firstName": "string",
"lastName": "string",
"esbId": "string",
"position": "string",
"jerseyNumber": 0,
"teamAbbr": "string",
"headshot": "string"
}
]
}
如果我獲得 team.logo 並將其添加到 teamPlayers 中的每個玩家,可能會更簡單。
就像一個建議,你為什么不創建一個接受多個團隊 ID 的端點,這樣你就不需要向服務器發送多個請求,它可以一次返回數組中的所有數據? 此外,從該端點返回一個team
和一個teamPlayers
密鑰的設計有點可疑,至少在語義上是這樣。 無論如何,這是我最好的嘗試:
async function loadTeams(endPoints, teams, authKey) {
axios.defaults.headers.common['Authorization'] = authKey;
const requests = teams.map(teamId =>
axios.get(endPoints.roster + teamId).then(res => res.data, e => {
console.error(e);
return { teamPlayers: [], team: [] };
})
);
const allTeamData = await Promise.all(requests);
// Following variables will aggregate ALL players from ALL teams and
// ALL logos (? it seems your logos are arrays, but that's a bit weird)
const allTeamPlayers = [], allTeamLogos = [];
for (const { teamPlayers, team } of allTeamData) {
allTeamPlayers.push(...teamPlayers); // spread optional
allTeamLogos.push(...team); // again, spread optional
}
dispatch({ type: 'SET_PLAYERS', value: allTeamPlayers });
dispatch({ type: 'SET_TEAM_LOGOS', value: allTeamLogos });
return { teamPlayers: allTeamPlayers, team: allTeamLogos };
}
現在您可以調用 function 並獲取結果的teamPlayers
或team
密鑰以獲取您需要的任何內容。
為避免多次獲取同一團隊,您可以緩存結果。 例如,如果這是 redux 商店,您可以派遣團隊並將他們放置在您的 redux state 中。 總而言之,您可以編寫一個異步 function 來從存儲中檢索團隊或在尚未獲取時獲取。
// Not sure how you are getting "dispatch" earlier, but assuming you've got a getState as well...
const inProgress = new Map();
async function loadTeam(endPoints, teamId, authKey) {
const { teams } = getState();
if (teamId in teams) {
return teams[teamId];
}
let promise = inProgress.get(teamId);
if (!promise) {
axios.defaults.headers.common['Authorization'] = authKey;
promise = axios.get(endPoints.roster + teamId);
inProgress.set(teamId, promise);
}
const { data: team } = await promise;
inProgress.delete(teamId);
// TODO: add a reducer that puts this team in your state
dispatch({ type: 'SET_TEAM', payload: { teamId, team } });
return team;
}
現在,如果您使用此loadTeam
function,您不必擔心重復提取:
async function loadRosters(endPoints, teams, authKey) {
axios.defaults.headers.common['Authorization'] = authKey;
const requests = teams.map(teamId => loadTeam(endPoints, teamId, authKey));
const results = (await Promise.all(requests))
.map(team => team.teamPlayers)
.flat();
dispatch({ type: 'SET_PLAYERS', value: results });
return results;
}
我想通了,但如果您認為有更有效的解決方案,請告訴我。
async function loadRosters(endPoints, teams, authKey) {
axios.defaults.headers.common['Authorization'] = authKey;
const requests = teams.map(teamId => {
try {
return axios.get(endPoints.roster + teamId).then(r => r.data);
} catch (e) {
//
}
return [];
});
const results = (await Promise.all(requests)).flat();
dispatch({ type: 'SET_PLAYERS', value: results.map(r => r.teamPlayers).flat(Infinity) });
dispatch({ type: 'SET_TEAM_LOGOS', value: results.map(r => r.team) });
return results;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.