2016-09-30 1 views
3

私はこの問題を永遠に思えるものに固執しました。 私はちょうど私がやろうとしています何等のノードの約束から返されたオブジェクトをループして次のノードに送ります。

をノードに入る、との約束のまわりで私の頭を取得し始めていますが楽しんでるの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); 
     } 

    }); 

    }) 

} 

私は、このデータのすべてを返す方法は次のとおりです。

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

しかし、これはundefinedを返します。私はgetArtists関数に単一のプレイリストurlを渡した場合にのみ動作させることができます。問題は、処理方法がわからないforEachループです。

ご協力いただきありがとうございます。

+0

あなたのために、あなたは約束を返さないので、あなたのための約束はありません。 Bluebirdの約束を使用している場合、それはPromise.mapを持っています。あなたのforEachをこれに置き換えて、そのようなPromise.mapを返すようにしてください。 – Keith

+0

約束どおりに読んだら、あなたのコード例では結局それをクリックしました。 – Ivan

答えて

4

あなたは、アクションの配列の完了を待つ約束を作るために[].map()Promise.all()の組み合わせを使用することができます。

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

は、チェーンへの約束のためにあなたが値またはAを返さなければならないことを覚えておいてくださいあなたの.then()ハンドラから約束してください。 .forEach()は何時でもundefinedを返します。まず

は、我々は、我々が返さPromise.all()を約束の配列を渡し、getArtist.map()を使用して、約束の配列にプレイリストの配列を回す解決単一プロミスときアレイ解決内のすべての約束(または最初に拒否すると拒否します)。

+0

こんにちはマダラ、あなたは私の日を救った - ありがとう!よくやった –

関連する問題