为了账号安全,请及时绑定邮箱和手机立即绑定

链接映射公理/API 调用

链接映射公理/API 调用

德玛西亚99 2022-08-27 09:47:38
对于我正在使用的API,我必须反弹3个单独的端点才能获得所需的数据。我被困在最后一个端点上,这让我发疯。以下是我目前正在做(或试图做)的要点。直接调用终结点 1。通过 map 处理数据(以返回我特别需要的数据),然后推送到 ARRAY 1。数组 1 完成处理后,我将 ARRAY 1 的数据映射到终结点 2,以对其每个 ID 进行 API 调用,然后将其推送到 ARRAY 2。数组 2 完成处理后,我将 ARRAY 2 的数据映射到终结点 3,以对其每个 ID 进行 API 调用,然后将其推送到 ARRAY 3。所有这些步骤都包含在一个承诺中,该承诺通过3个完整的数组进行解析。步骤1和2做得很好,但是我已经为步骤3尝试了一百万种不同的东西,并且它不断返回。处理这个问题的最佳方式是什么?任何帮助将不胜感激!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();      });    });
查看完整描述

1 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

我认为你最好遵循一种更简单的方法,使用异步/等待。这使我们能够以更易于遵循的方式构建代码。如果我们有大量的.then()和新的承诺等,它会变得非常混乱,非常快!


我已经像这样重组了,我认为这更容易遵循,并希望调试!


我们可以遍历 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.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();

}



查看完整回答
反对 回复 2022-08-27
  • 1 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号