链接映射公理/API 调用

对于我正在使用的API,我必须反弹3个单独的端点才能获得所需的数据。我被困在最后一个端点上,这让我发疯。以下是我目前正在做(或试图做)的要点。

  1. 直接调用终结点 1。通过 map 处理数据(以返回我特别需要的数据),然后推送到 ARRAY 1。

  2. 数组 1 完成处理后,我将 ARRAY 1 的数据映射到终结点 2,以对其每个 ID 进行 API 调用,然后将其推送到 ARRAY 2。

  3. 数组 2 完成处理后,我将 ARRAY 2 的数据映射到终结点 3,以对其每个 ID 进行 API 调用,然后将其推送到 ARRAY 3。

  4. 所有这些步骤都包含在一个承诺中,该承诺通过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();

      });

    });


德玛西亚99
浏览 95回答 1
1回答

MYYA

我认为你最好遵循一种更简单的方法,使用异步/等待。这使我们能够以更易于遵循的方式构建代码。如果我们有大量的.then()和新的承诺等,它会变得非常混乱,非常快!我已经像这样重组了,我认为这更容易遵循,并希望调试!我们可以遍历 getXXX 函数中的每个项目,或者我们可以使用 Promise.all,这两种方法都有效,尽管后者可能更高性能。我已经在getTracks()中使用了这个router.get("/", async (req, res) => {&nbsp; &nbsp; let options = {&nbsp; &nbsp; &nbsp; &nbsp; headers: {&nbsp; &nbsp; &nbsp; &nbsp; 'Authorization': `Bearer ${token}`,&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; if (!token) {&nbsp; &nbsp; &nbsp; &nbsp; res.send({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message: 'Please login to retrieve data',&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; const url = 'https://api.spotify.com/v1/me/following?type=artist&limit=50';&nbsp; &nbsp; let artists = await getArtists(url, options);&nbsp; &nbsp; console.log ("Artists (length):", artists.length );&nbsp; &nbsp; let albums = await getAlbums(artists, options);&nbsp; &nbsp; console.log ("Albums (length):", albums.length );&nbsp; &nbsp; let tracks = await getTracks(albums, options);&nbsp; &nbsp; console.log("Tracks (length):", tracks.length);&nbsp; &nbsp; res.send( { albums, artists, tracks } );&nbsp; &nbsp;}async function getArtists(url, options, maxLoopCount = 100) {&nbsp; &nbsp; let artists = [];&nbsp; &nbsp; let count = 0;&nbsp; &nbsp; do {&nbsp; &nbsp; &nbsp; &nbsp; console.log(`getArtists: Page #${++count}...`);&nbsp; &nbsp; &nbsp; &nbsp; let artistResp = await getArtistsPage(url, options);&nbsp; &nbsp; &nbsp; &nbsp; artists.push(...artistResp.artistList);&nbsp; &nbsp; &nbsp; &nbsp; url = artistResp.next;&nbsp; &nbsp; } while (url && count < maxLoopCount) ;&nbsp; &nbsp; return artists;}async function getArtistsPage(url, options) {&nbsp; &nbsp; let response = await axios.get(url, options);&nbsp; &nbsp; let artistList = response.data.artists.items.map(artist => ({&nbsp; &nbsp; &nbsp; &nbsp; url: artist.external_urls.spotify,&nbsp; &nbsp; &nbsp; &nbsp; name: artist.name,&nbsp; &nbsp; &nbsp; &nbsp; images: artist.images,&nbsp; &nbsp; &nbsp; &nbsp; id: artist.id,&nbsp; &nbsp; &nbsp; &nbsp; genres: artist.genres,&nbsp; &nbsp; }));&nbsp; &nbsp; let next = response.data.artists.next;&nbsp; &nbsp; return { artistList, next}};async function getAlbums(artists, options, sliceCount = 50) {&nbsp; &nbsp; let albums = [];&nbsp; &nbsp; for(let artist of artists) {&nbsp; &nbsp; &nbsp; &nbsp; let response = await axios.get(`https://api.spotify.com/v1/artists/${artist.id}/albums?market=us&include_groups=single,appears_on`, options);&nbsp; &nbsp; &nbsp; &nbsp; albums.push(...response.data.items);&nbsp; &nbsp; }&nbsp; &nbsp; const filtered = albums.filter((curr, index, self) => self.findIndex(t => t.id === curr.id) === index);&nbsp; &nbsp; const sorted = filtered.sort((a, b) => (b.release_date > a.release_date) ? 1 : -1); // change data to filtered to filter duplicates&nbsp; &nbsp; const sliced = sorted.slice(0, sliceCount);&nbsp; &nbsp; return sliced;}async function getTracks(albums, options) {&nbsp; &nbsp; let promises = albums.map(album => axios.get(`https://api.spotify.com/v1/albums/${album.id}/tracks`, options));&nbsp; &nbsp; let responseList = await Promise.all(promises);&nbsp; &nbsp; return responseList.map(response => response.data.items).flat();}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript