Javascript 这是一个有承诺的函数。在这个函数中,我再次调用这个函数(递归)。如何等待递归承诺得到解决?
我需要逐一运行两个功能:Javascript 这是一个有承诺的函数。在这个函数中,我再次调用这个函数(递归)。如何等待递归承诺得到解决?,javascript,recursion,promise,es6-promise,Javascript,Recursion,Promise,Es6 Promise,我需要逐一运行两个功能:getUserPlaylists(接收播放列表)和getplaylistics(接收所提供播放列表的曲目) 一个响应最多可以有50首曲目,因此如果我想获得其余曲目,我需要使用PageToken。问题是我不能让递归函数getplaylitracks等待递归完成 function getPlaylistsWithTracks () { return new Promise((resolve, reject) => { getUserPlaylists()
getUserPlaylists
(接收播放列表)和getplaylistics
(接收所提供播放列表的曲目)
一个响应最多可以有50首曲目,因此如果我想获得其余曲目,我需要使用PageToken
。问题是我不能让递归函数getplaylitracks
等待递归完成
function getPlaylistsWithTracks () {
return new Promise((resolve, reject) => {
getUserPlaylists()
.then(function (playlists) {
playlists.forEach(
async function (playlistObj) {
await getPlaylistTracks(playlistObj).then(function (tracks) {
playlistObj['tracks'] = tracks
})
})
console.log('resolve')
resolve(playlists)
})
})
}
function getPlaylistTracks (playlistObj, pageToken) {
return new Promise((resolve, reject) => {
let playlistTracks = []
let requestOptions = {
'playlistId': playlistObj['youtubePlaylistId'],
'maxResults': '50',
'part': 'snippet'
}
if (pageToken) {
console.log('pageToken:', pageToken)
requestOptions.pageToken = pageToken
}
let request = gapi.client.youtube.playlistItems.list(requestOptions)
request.execute(function (response) {
response['items'].forEach(function (responceObj) {
let youtubeTrackTitle = responceObj.snippet.title
if (youtubeTrackTitle !== 'Deleted video') {
let youtubeTrackId = responceObj.snippet.resourceId.videoId
playlistTracks.push({
youtubePlaylistId: playlistObj.playlistId,
youtubePlaylistTitle: playlistObj.playlistTitle,
youtubeTrackId: youtubeTrackId,
youtubeTrackTitle: youtubeTrackTitle,
})
}
})
// Here I need to wait a bit
if (response.result['nextPageToken']) {
getPlaylistTracks(playlistObj, response.result['nextPageToken'])
.then(function (nextPageTracks) {
playlistTracks = playlistTracks.concat(nextPageTracks)
})
}
})
resolve(playlistTracks)
})
}
getPlaylistsWithTracks()
在控制台中,我看到了下一个:
> resolve
> pageToken: 123
> pageToken: 345
但是,我想看到解决最后一个问题
如何等待递归执行 避免使用,并适当使用
此外,递归没有什么特别之处。它就像您希望等待的任何其他承诺返回函数调用一样—将其放入然后
链或等待
中。(后者要容易得多)
避免错误,并妥善处理
此外,递归没有什么特别之处。它就像您希望等待的任何其他承诺返回函数调用一样—将其放入然后
链或等待
中。(后者要容易得多)
将解析调用放入请求中response@Occam“斯拉佐没有帮忙。控制台中的顺序仍然相同(resolve
1st,然后pageToken
s)这里我需要稍等一下-您需要在内部解析。然后在那里。。。无nextPageToken
情况下的解析应在else
块中完成,将解析调用放入请求中response@Occam“斯拉佐没有帮忙。控制台中的顺序仍然相同(resolve
1st,然后pageToken
s)这里我需要稍等一下-您需要在内部解析。然后在那里。。。无nextPageToken
情况下的解析应该在else
块中完成,现在可以工作,但速度比以前慢10-15倍。是因为async\Wait吗?速度可以提高吗?这是因为getplayliswithtracks
中的循环现在是顺序的,所有的事情都被正确地等待着。关于如何同时向曲目发出to请求,请参阅我答案中的第二个链接。现在我看到了正确的模式。非常感谢您的帮助和有用的链接!编辑:我根据您链接的解决方案更改了循环,速度恢复。再次感谢:)它现在可以工作了,但速度比以前慢了10-15倍。是因为async\Wait吗?速度可以提高吗?这是因为getplayliswithtracks
中的循环现在是顺序的,所有的事情都被正确地等待着。关于如何同时向曲目发出to请求,请参阅我答案中的第二个链接。现在我看到了正确的模式。非常感谢您的帮助和有用的链接!编辑:我根据您链接的解决方案更改了循环,速度恢复。再次感谢:)
async function getPlaylistsWithTracks() {
const playlists = await getUserPlaylists();
for (const playlistObj of playlists) {
const tracks = await getPlaylistTracks(playlistObj);
playlistObj.tracks = tracks;
}
console.log('resolve')
return playlists;
}
async function getPlaylistTracks(playlistObj, pageToken) {
let playlistTracks = []
let requestOptions = {
'playlistId': playlistObj['youtubePlaylistId'],
'maxResults': '50',
'part': 'snippet'
}
if (pageToken) {
console.log('pageToken:', pageToken)
requestOptions.pageToken = pageToken
}
let request = gapi.client.youtube.playlistItems.list(requestOptions)
const response = await new Promise((resolve, reject) => {
request.execute(resolve); // are you sure this doesn't error?
});
response['items'].forEach(function (responceObj) {
let youtubeTrackTitle = responceObj.snippet.title
if (youtubeTrackTitle !== 'Deleted video') {
let youtubeTrackId = responceObj.snippet.resourceId.videoId
playlistTracks.push({
youtubePlaylistId: playlistObj.playlistId,
youtubePlaylistTitle: playlistObj.playlistTitle,
youtubeTrackId: youtubeTrackId,
youtubeTrackTitle: youtubeTrackTitle,
})
}
})
if (response.result['nextPageToken']) {
const nextPageTracks = await getPlaylistTracks(playlistObj, response.result['nextPageToken']);
playlistTracks = playlistTracks.concat(nextPageTracks);
}
return playlistTracks;
}