需要帮助修复 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)应该是最后执行的,但事实并非如此。
正如您所建议的那样,不要混合使用 then
和 async/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);
};
getArtist
不需要是异步的,因为 getData
必须是一个异步函数,return 是一个承诺,所以 getArtist 会自动 return 一个承诺。
getGenre
另一方面,必须是异步的,因为您需要在使用它们之前检索所有类型,而这是异步发生的。
getAllGenres
是您必须小心的地方,您将并行抛出多个异步调用,这是您需要使用 Promise.all
处理的场景,您可以在这里找到很多资源关于这个特定主题。
好的,我有以下 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)应该是最后执行的,但事实并非如此。
正如您所建议的那样,不要混合使用 then
和 async/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);
};
getArtist
不需要是异步的,因为getData
必须是一个异步函数,return 是一个承诺,所以 getArtist 会自动 return 一个承诺。getGenre
另一方面,必须是异步的,因为您需要在使用它们之前检索所有类型,而这是异步发生的。getAllGenres
是您必须小心的地方,您将并行抛出多个异步调用,这是您需要使用Promise.all
处理的场景,您可以在这里找到很多资源关于这个特定主题。