Javascript 链接映射的axios/API调用
对于我正在使用的API,我必须从3个独立的端点反弹才能获得所需的数据。我被困在最后一个终点,这让我发疯。以下是我目前正在做(或试图做)的要点Javascript 链接映射的axios/API调用,javascript,node.js,axios,spotify,Javascript,Node.js,Axios,Spotify,对于我正在使用的API,我必须从3个独立的端点反弹才能获得所需的数据。我被困在最后一个终点,这让我发疯。以下是我目前正在做(或试图做)的要点 直接调用端点1。通过map处理数据(返回我特别需要的数据),然后推送到ARRAY 1 处理完数组1后,我将数组1的数据映射到端点2,为每个ID调用API,然后将其推送到数组2 一旦处理完数组2,我就将数组2的数据映射到端点3,为它的每个ID进行API调用,然后将其推送到数组3 所有这些步骤都包含在一个承诺中,该承诺使用3个完整的数组进行解析 第1步和第2步
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(`https://api.spotify.com/v1/artists/${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(`https://api.spotify.com/v1/albums/${item.id}/tracks`, options).then(response => {
tracks.push(...response.data.items);
});
});
};
if (token) {
const url = 'https://api.spotify.com/v1/me/following?type=artist&limit=50';
getArtists(url);
} else {
res.send({
message: 'Please login to retrieve data',
});
};
});
我认为您最好采用一种更简单的方法,使用async/await。这使我们能够以更容易理解的方式构造代码。如果我们有大量的.then()和新的承诺等,它会变得非常混乱,非常快 我已经这样重组了,我认为这更容易遵循,希望能够调试 我们可以循环getXXX函数中的每一项,也可以使用Promise.all,这两种方法都有效,尽管后者可能更有效 我在getTracks()中使用了这个
router.get(“/”,异步(req,res)=>{
让选项={
标题:{
'Authorization':'Bearer${token}`,
}
}
如果(!令牌){
res.send({
消息:“请登录以检索数据”,
});
返回;
}
常量url=https://api.spotify.com/v1/me/following?type=artist&limit=50';
让艺术家=等待getArtists(url,选项);
console.log(“艺术家(长度):”,艺术家.length);
let albums=Wait getAlbums(艺术家、选项);
console.log(“相册(长度):”,Albums.length);
let tracks=等待获取(相册、选项);
log(“Tracks(length):”,Tracks.length);
res.send({专辑、艺术家、曲目});
}
异步函数getArtists(url、选项、maxLoopCount=100){
让艺术家=[];
让计数=0;
做{
log(`getArtists:Page#${++count}…`);
让artistResp=等待getArtistsPage(url,选项);
艺术家。推手(…艺术家;艺术家);
url=artistResp.next;
}while(url&&count({
url:artist.external_url.spotify,
姓名:艺人姓名,
图片:艺术家图片,
id:artist.id,
类型:艺术家。类型,
}));
让next=response.data.artists.next;
返回{artistList,next}
};
异步函数getAlbums(艺术家、选项、切片计数=50){
让相册=[];
为了(让艺术家成为艺术家中的艺术家){
let response=等待axios.get(`https://api.spotify.com/v1/artists/${artist.id}/albums?market=us&include\u groups=single,出现在`,选项);
相册。推送(…响应。数据。项);
}
const filtered=albums.filter((curr,index,self)=>self.findIndex(t=>t.id==curr.id)==index);
const sorted=filtered.sort((a,b)=>(b.release\u date>a.release\u date)?1:-1);//将数据更改为filtered以过滤重复项
const sliced=sorted.slice(0,sliceCount);
返回切片;
}
异步函数(相册、选项){
让承诺=albums.map(album=>axios.get(`https://api.spotify.com/v1/albums/${album.id}/tracks`,options));
让响应列表=等待承诺。全部(承诺);
返回responseList.map(response=>response.data.items.flat();
}
我认为您最好采用一种更简单的方法,使用async/await。这使我们能够以一种更容易理解的方式构造代码。如果我们有大量的.then()和新承诺等,它会很快变得非常混乱
我已经这样重组了,我认为这更容易遵循,希望能够调试
我们可以循环getXXX函数中的每一项,也可以使用Promise.all,这两种方法都有效,尽管后者可能更有效
我在getTracks()中使用了这个
router.get(“/”,异步(req,res)=>{
让选项={
标题:{
'Authorization':'Bearer${token}`,
}
}
如果(!令牌){
res.send({
消息:“请登录以检索数据”,
});
返回;
}
常量url=https://api.spotify.com/v1/me/following?type=artist&limit=50';
让艺术家=等待getArtists(url,选项);
console.log(“艺术家(长度):”,艺术家.length);
let albums=Wait getAlbums(艺术家、选项);
console.log(“相册(长度):”,Albums.length);
let tracks=等待获取(相册、选项);
log(“Tracks(length):”,Tracks.length);
res.send({专辑、艺术家、曲目});
}
异步函数getArtists(url、选项、maxLoopCount=100){
让艺术家=[];
让计数=0;
做{
log(`getArtists:Page#${++count}…`);
让artistResp=等待getArtistsPage(url,选项);
艺术家。推手(…艺术家;艺术家);
url=artistResp.next;
}while(url&&count({
url:artist.external_url.spotify,
姓名:艺人姓名,
图片:艺术家图片,
id:artist.id,
类型:艺术家。类型,
}));
让next=response.data.artists.next;
返回{artistList,next}
};
异步函数getAlbums(艺术家、选项、切片计数=50){
让相册=[];
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.com/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.com/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.com/v1/albums/${album.id}/tracks`, options));
let responseList = await Promise.all(promises);
return responseList.map(response => response.data.items).flat();
}