簡體   English   中英

如何結合這兩個異步功能?

[英]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 並獲取結果的teamPlayersteam密鑰以獲取您需要的任何內容。

為避免多次獲取同一團隊,您可以緩存結果。 例如,如果這是 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM