链接映射的axios / API调用"/>
链接映射的axios / API调用
对于我正在使用的API,我必须从3个单独的端点反弹以获取所需的数据。我被困在最后一个端点,这让我发疯。这是我目前正在(或尝试做)的要点。
- 直接调用ENDPOINT1。通过map处理数据(以返回我特别需要的数据),然后推送到ARRAY 1。
- [ARRAY 1完成处理后,我将ARRAY 1的数据映射为对其ID的每个ID进行API调用,然后将其推入ARRAY 2。
- [ARRAY 2完成处理后,我将ARRAY 2的数据映射为对其ID的每个ID进行API调用,然后将其推入ARRAY 3。
- 所有这些步骤都包装在一个可以解决3个完整数组的诺言中。
第1步和第2步做得很好,但是我在第3步中尝试了100万种不同的方法,并且一直在返回。处理此问题的最佳方法是什么?任何帮助将不胜感激!
router.get("/", (req, res) => {
let artists = [];
let albums = [];
let tracks = [];
const options = {
headers: {
'Authorization': `Bearer ${token}`,
},
};
function getArtists(url) {
return new Promise(resolve => {
axios.get(url, options).then(response => {
artists.push(...response.data.artists.items.map(artist => ({
url: artist.external_urls.spotify,
name: artist.name,
images: artist.images,
id: artist.id,
genres: artist.genres,
})));
let next = response.data.artists.next;
if (next !== null) {
getArtists(next);
} else {
resolve(getAlbums().then(() => getTracks().then(() => res.send({artists, albums, tracks}))));
};
});
});
};
let getAlbums = () => {
return new Promise(resolve => {
const requests = artists.map(item => {
return axios.get(`/${item.id}/albums?market=us&include_groups=single,appears_on`, options).then(response => {
albums.push(...response.data.items);
});
});
Promise.all(requests).then(() => {
const filtered = albums.filter((curr, index, self) => self.findIndex(t => t.id === curr.id) === index);
const sorted = filtered.sort((a, b) => (b.release_date > a.release_date) ? 1 : -1); // change data to filtered to filter duplicates
const sliced = sorted.slice(0, 50);
albums = sliced;
// res.send({artists, albums});
resolve();
});
});
};
let getTracks = () => {
albums.map(item => {
return axios.get(`/${item.id}/tracks`, options).then(response => {
tracks.push(...response.data.items);
});
});
};
if (token) {
const url = ';limit=50';
getArtists(url);
} else {
res.send({
message: 'Please login to retrieve data',
});
};
});
回答如下:我认为您最好使用一种简单的方法,即使用async / await。这使我们能够以更容易理解的方式来构造代码。如果我们有.then()和新Promises等的负载,它将变得非常混乱,非常迅速!
我已经进行了这样的重组,我认为这更容易理解,希望可以调试!
[我们可以遍历getXXX函数中的每个项目,或者我们可以使用Promise.all,尽管这两种方法可能更有效,但是两种方法都可行。
我已经在getTracks()中使用了它
router.get("/", async (req, res) => {
let options = {
headers: {
'Authorization': `Bearer ${token}`,
}
}
if (!token) {
res.send({
message: 'Please login to retrieve data',
});
return;
}
const url = 'https://api.spotify/v1/me/following?type=artist&limit=50';
let artists = await getArtists(url, options);
console.log ("Artists (length):", artists.length );
let albums = await getAlbums(artists, options);
console.log ("Albums (length):", albums.length );
let tracks = await getTracks(albums, options);
console.log("Tracks (length):", tracks.length);
res.send( { albums, artists, tracks } );
}
async function getArtists(url, options, maxLoopCount = 100) {
let artists = [];
let count = 0;
do {
console.log(`getArtists: Page #${++count}...`);
let artistResp = await getArtistsPage(url, options);
artists.push(...artistResp.artistList);
url = artistResp.next;
} while (url && count < maxLoopCount) ;
return artists;
}
async function getArtistsPage(url, options) {
let response = await axios.get(url, options);
let artistList = response.data.artists.items.map(artist => ({
url: artist.external_urls.spotify,
name: artist.name,
images: artist.images,
id: artist.id,
genres: artist.genres,
}));
let next = response.data.artists.next;
return { artistList, next}
};
async function getAlbums(artists, options, sliceCount = 50) {
let albums = [];
for(let artist of artists) {
let response = await axios.get(`https://api.spotify/v1/artists/${artist.id}/albums?market=us&include_groups=single,appears_on`, options);
albums.push(...response.data.items);
}
const filtered = albums.filter((curr, index, self) => self.findIndex(t => t.id === curr.id) === index);
const sorted = filtered.sort((a, b) => (b.release_date > a.release_date) ? 1 : -1); // change data to filtered to filter duplicates
const sliced = sorted.slice(0, sliceCount);
return sliced;
}
async function getTracks(albums, options) {
let promises = albums.map(album => axios.get(`https://api.spotify/v1/albums/${album.id}/tracks`, options));
let responseList = await Promise.all(promises);
return responseList.map(response => response.data.items).flat();
}
更多推荐
链接映射的axios / API调用
发布评论