什么类型的Object需要返回等待,以避免未定义



让我在这里尽可能清楚。

  1. 我调用getVids函数
  2. 它直接进入return await Promise.all...
  3. 然后它进入递归,其中singleChannelWithNewVids对象与videos数组一起转储
  4. 当没有更多的res.data.nextPageToken作为响应时,我将返回稍大的singleChannelWithNewVids对象
  5. 我的console.log(singleChannelWithNewVids, 'RETURING')行记录此对象存在
  6. 但是当const gettingVids = await getVidsWithPage(e)发生并且我记录console.log('gettingVids', gettingVids)时,它记录该对象是未定义的

为什么?我已经尝试了所有你可以看到评论的东西,所有东西都返回未定义,但记录了一个正常的对象。。。

const channelsWithPlaylistIds = [{
channelName: 'TokyoStreetView - Japan The Beautiful',
channelId: 'UCAxMEpfzdJ2dkrplSWehgcA',
playlistIds: [ 'UUAxMEpfzdJ2dkrplSWehgcA' ],
videos: []
}]
async getVids(channelsWithPlaylistIds) {
const getVidsWithPage = async (e, pageToken) => {
return axios(this.playlistItemsUrl(e.playlistIds[0], pageToken)).then(async res => {
const singleChannelWithNewVids = { ...e, videos: [...e.videos, ...res.data.items]}
if(res.data.nextPageToken) {
console.log('RECUSING')
await getVidsWithPage(singleChannelWithNewVids, res.data.nextPageToken)
} else {
console.log(singleChannelWithNewVids, 'RETURING')
return Promise.resolve(singleChannelWithNewVids)
// return new Promise(resolve => { resolve(singleChannelWithNewVids) })
// return Promise.all([singleChannelWithNewVids])
// return singleChannelWithNewVids
}
})
}
return await Promise.all(channelsWithPlaylistIds.map(async e => {
const gettingVids = await getVidsWithPage(e)
console.log('gettingVids', gettingVids)
return gettingVids
}))
}

是的,我不使用分号,现在是2020年,处理它

您所拥有的是一个递归函数,该函数在除最后一个函数外的所有情况下都不会返回。

要理解这一点,请想象getVidsWithPage第一次执行的线程。它进行一个axios调用,看到if(res.data.nextPageToken)为true,输入if语句,然后调用一个函数(在这种情况下是函数本身,但这实际上并不重要(,然后结束执行,而不返回任何东西

在递归过程中,只有getVidsWithPage的最后一次调用返回,但它返回其中一个:

await getVidsWithPage(singleChannelWithNewVids, res.data.nextPageToken)

并且该结果被丢弃。

无论如何,只需在那里添加一个return

return await getVidsWithPage(singleChannelWithNewVids, res.data.nextPageToken)

顺便说一句,在看到你的评论后,我想建议一个无关的改进-YSK,每个函数自动标记为async,总是返回一个Promise。这很有用,这意味着您的Promise.resolve是多余的,您永远不需要使用.then()。您可以重写当前的代码,使其更加简洁,如下所示:

getVids(channelsWithPlaylistIds) {
const getVidsWithPage = async (e, pageToken) => {
let res = await axios(this.playlistItemsUrl(e.playlistIds[0], pageToken))
const singleChannelWithNewVids = { ...e, videos: [...e.videos, ...res.data.items]}
if(res.data.nextPageToken) {
console.log('RECUSING')
return getVidsWithPage(singleChannelWithNewVids, res.data.nextPageToken)
} else {
console.log(singleChannelWithNewVids, 'RETURING')
return singleChannelWithNewVids
}
}
return Promise.all(channelsWithPlaylistIds.map(getVidsWithPage))
}

最新更新