Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 循环从节点promise返回的对象,并将其馈送到下一个_Javascript_Node.js_Promise - Fatal编程技术网

Javascript 循环从节点promise返回的对象,并将其馈送到下一个

Javascript 循环从节点promise返回的对象,并将其馈送到下一个,javascript,node.js,promise,Javascript,Node.js,Promise,我一直被这个问题困扰着,这似乎是一个永恒的问题。 我刚进入节点,开始思考承诺等问题 我想做的是从Spotify API获取数据,我要做的第一件事是获取自己的播放列表: function getPlaylists(access_token) { var options = { url: 'https://api.spotify.com/v1/me/playlists', headers: { 'Authorization': 'Bearer ' + access_

我一直被这个问题困扰着,这似乎是一个永恒的问题。 我刚进入节点,开始思考承诺等问题

我想做的是从Spotify API获取数据,我要做的第一件事是获取自己的播放列表:

function getPlaylists(access_token) {

    var options = {
      url: 'https://api.spotify.com/v1/me/playlists',
      headers: { 'Authorization': 'Bearer ' + access_token },
      json: true
    };

    return new Promise(function(resolve, reject) {

      request.get(options, function(error, response, body) {
        var playlists = body.items;
        var playlistArray = [];
        playlists.forEach(function(playlist) {
          var name = playlist.name;
          var url = playlist.tracks.href;

          playlistArray.push(url);
        });

        if(!error) {
          resolve(playlistArray);
        } else {
          reject(error);
        }

    });

  });
}
function getArtists(url,access_token) {

  var params = {
    url: url,
    headers: { 'Authorization': 'Bearer ' + access_token },
    json: true
  };

  return new Promise(function(resolve, reject) {

    request.get(params, function(error, response, body) {

        var tracks = body.items;
        var artistArray = [];
        tracks.forEach(function(artists) {
          let allArtists = artists.track.artists;
          allArtists.forEach(function(artist) {
              artistArray.push(artist);
          });
        })

        if(!error) {
          resolve(artistArray);
        } else {
          reject(error);
        }

    });

  })

}
好的,到目前为止还不错。现在我还想从这些播放列表中找到艺术家:

function getPlaylists(access_token) {

    var options = {
      url: 'https://api.spotify.com/v1/me/playlists',
      headers: { 'Authorization': 'Bearer ' + access_token },
      json: true
    };

    return new Promise(function(resolve, reject) {

      request.get(options, function(error, response, body) {
        var playlists = body.items;
        var playlistArray = [];
        playlists.forEach(function(playlist) {
          var name = playlist.name;
          var url = playlist.tracks.href;

          playlistArray.push(url);
        });

        if(!error) {
          resolve(playlistArray);
        } else {
          reject(error);
        }

    });

  });
}
function getArtists(url,access_token) {

  var params = {
    url: url,
    headers: { 'Authorization': 'Bearer ' + access_token },
    json: true
  };

  return new Promise(function(resolve, reject) {

    request.get(params, function(error, response, body) {

        var tracks = body.items;
        var artistArray = [];
        tracks.forEach(function(artists) {
          let allArtists = artists.track.artists;
          allArtists.forEach(function(artist) {
              artistArray.push(artist);
          });
        })

        if(!error) {
          resolve(artistArray);
        } else {
          reject(error);
        }

    });

  })

}
我返回所有这些数据的方式是:

getPlaylists(access_token)
     .then(function(playlists) {

       playlists.forEach(function(playlist) {
          getArtists(playlist,access_token)
               .then(function(artist) {
                    return artist;
               });
     });


     }).then(function(artists) {
        console.log("getting artists",artists);
     }).catch(function(error) {
        console.log(error);
})
但是,这返回未定义的。只有将一个播放列表url传递给getArtists函数,我才能使它工作——问题是forEach循环,我不知道如何处理它


非常感谢您的帮助

您可以结合使用
[].map()
Promise.all()
来做出承诺,等待一系列操作完成:

getPlaylists(access_token)
  .then(playlists => Promise.all(playlists.map(playlist => 
    getArtists(playlist, access_token)))
  .then(artists => {
    // use here
  });
请记住,对于要链接的承诺,必须从
处理程序返回值或承诺
.forEach()
始终返回
未定义的
,无论发生什么情况


首先,我们使用
.map()
getArtist
将播放列表数组转换为承诺数组,然后将该承诺数组传递给
Promise.all()
,该数组返回单个承诺,该承诺在数组中的所有承诺都解决时解决(或在第一个承诺被拒绝时拒绝).

你的承诺不是承诺,因此你也不会兑现承诺。如果你使用蓝鸟承诺,它有一个Promise.map。用这个替换你的forEach,并确保你返回了这样的Promise.map,你应该准备好了。奇怪的是,在阅读了大量关于promises的文章后,你的代码示例终于让它点击了。