循环从节点promise返回的对象并将其提供给下一个.then

时间:2016-09-30 21:26:52

标签: javascript node.js promise

我一直坚持这个问题似乎永恒。 我刚刚进入节点,并开始了解承诺等。

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

import java.io.File;
import java.util.Scanner;

public class Reemplazar {

    public static void main(String[] args) throws Exception {

        Scanner archivo = new Scanner(new File("prueba.txt"));

            while(archivo.hasNextLine()) {
                String frase = archivo.nextLine();

                for (int i = 0; i < frase.length(); i++) {
                    char current = frase.charAt(i);

                    if  (current == 0xe1) {
                        System.out.println("contiene la á: '"+frase+"'");
                     }

                    if  (current == 0xe9) {
                        System.out.println("contiene es la é: '"+frase+"'");
                    }

                }
          }
     }
}

好吧,到目前为止一切顺利。现在我还想从这些播放列表中获取艺术家:

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);
        }

    });

  })

}

但是,这会返回undefined。我只能将一个播放列表url传递给getArtists函数才能使它工作 - 问题是我不知道如何处理的forEach循环。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:4)

您可以使用[].map()Promise.all()的组合制作一个等待完成一系列操作的Promise:

getPlaylists(access_token)
  .then(playlists => Promise.all(playlists.map(playlist => 
    getArtists(playlist, access_token)))
  .then(artists => {
    // use here
  });

请记住,对于Promise链,您必须.then()处理程序返回值或Promise。无论如何,.forEach()始终会返回undefined

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