需要帮助修复 Javascript 执行流程。 Console.log 正在打开时重新验证

Need help fixing Javascript execution flow. Console.log is being revalidated upon opening

好的,我有以下 3 个功能可以帮助我根据艺术家 ID 收集 Spotify 流派。由于 Spotify 上的大多数曲目都有多个艺术家,我需要结合所有个人艺术家流派,以便以后可以使用它们。

我有以下3个功能:

const getArtist = async (artistId) => {
  console.log('4');
  const artistObject = await getData(
    'https://api.spotify.com/v1/artists/' + artistId
  ).then((artistObject) => {
    return artistObject;
  });
};
const getAllGenres = (artists) => {
  let artistGenres = [];
  console.log('2');

  artists.map(async (item) => {
    console.log('3');
    await getArtist(item.id).then(async (artist) => {
      console.log('5');
      await artist.genres.map((genre) => {
        if (artistGenres.indexOf(genre) == -1) {
          artistGenres.push(genre);
        }
      });
    });
  });

  return artistGenres;
};

const getGenre = (artists) => {
  console.log('1');
  const allgenres = getAllGenres(artists);

  console.log('6', allgenres);
}

每当我在控制台中检查 allgenres 的值时,它看起来是空的,但每当我单击箭头展开它时,它都有值。我知道这是因为每当我展开数组时它都会重新验证 allgenres 的值。

我在网上查找有关此问题的解决方案并遇到了 async/await。我已经试过了,不得不把 getAllGenres 变成一个 promise。不是问题,但没有解决问题。

我添加了一些 console.logs 来帮助我理解当前的执行流程:

1
2
3
4
3
4
6 [] <- Revalidates after opening
5
5

据我了解console.log(6)应该是最后执行的,但事实并非如此。

正如您所建议的那样,不要混合使用 thenasync/await 语法,因为这样会使代码更难阅读,我无法测试代码,因为我没有访问权限api,但这应该有效:

const getArtist = (artistId) => {
  return getData('https://api.spotify.com/v1/artists/' + artistId);
};

const getAllGenres = async (artists) => {
  let artistGenres = [];
  await Promise.all(
    artists.map(async (item) => {
      const artist = await getArtist(item.id);
      artist.genres.forEach((genre) => {
        if (artistGenres.indexOf(genre) == -1) {
          artistGenres.push(genre);
        }
      });
    })
  );
  return artistGenres;
};

const getGenre = async (artists) => {
  const allgenres = await getAllGenres(artists);
  console.log(allgenres);
};
  1. getArtist 不需要是异步的,因为 getData 必须是一个异步函数,return 是一个承诺,所以 getArtist 会自动 return 一个承诺。
  2. getGenre 另一方面,必须是异步的,因为您需要在使用它们之前检索所有类型,而这是异步发生的。
  3. getAllGenres 是您必须小心的地方,您将并行抛出多个异步调用,这是您需要使用 Promise.all 处理的场景,您可以在这里找到很多资源关于这个特定主题。