之间具有顺序动态内容的并行承诺链

Parallel promise chain with sequential dynamic content in between

我无法解决如何将动态结果添加到 promise 链的问题,如果这可能的话,我已经到处寻找了。希望有人可以为我正在尝试完成的以下示例(它是一个小型音乐播放器)澄清或给我一个好的解决方案:

// API requests are done with a promise
let pfetch = (url) => Promise.resolve( $.ajax(...) )

// This will give me all playlists from a user
pfetch( 'USER-API-URL' )

    // The playlists i get have tracklists
    .then( results =>

        // When all playlists are fetched continue (Promise.all = parallel)
        Promise.all( results.playlists.map( playlist => pfetch(playlist.url) ) )
    )

    // Results of all playlists in arguments
    .then( playlists => 

        // Each playlist has tracks and next_url
        playlists.map( playlist => {

        /* playlist.tracks 
         * if (playlist.next_url) pfetch(playlist.next_url)
         * append results to playlist.tracks
         */

        })
    )

        //only continue if all all tracks are complete

    //can i do a Promise.join() in the previous step?
    .then( () => console.log('finished,yay!') )

一些曲目列表在他们的响应中有一个next_url,意思是,我还应该获取属于曲目列表的下一个url,这样我可以获得一个完整的tracklist.tracks.但是,这必须是顺序的,因为我不知道响应中是否有后续的 next_url。当没有 next_url 时,我完成了一个曲目列表,可以对下一个曲目列表做同样的事情(因此 .map)。

那么我的问题,你如何在 promises 中进行动态内容链接?我知道您可以使用 reduce 进行排序,但在这种情况下 next_url 的数量不固定。我考虑过递归,但还没有找到 Promise.each 的好例子。

提前点赞

如果你创建一个函数来递归处理一个播放列表url

var getPlaylistUrl = url => 
    pfetch(url).then(playlist => 
        playlist.next_url ? Promise.all([].concat.apply([playlist.tracks], getPlaylistUrl(playlist.next_url))) : playlist.tracks
    );

您应该能够按如下方式重写您的代码

pfetch('USER-API-URL')
.then(results => Promise.all(results.playlists.map(playlist => getPlaylistUrl(playlist.url))))
.then( playlists => {
    // playlists should be complete
})
.then( () => console.log('finished,yay!') );