我的问题与众不同:成功链接诺言后,我剩下列出文件和目录的单独数组,需要再次获取这些目录中的文件,将其添加到第一个文件列表中,最后根据所有已完成的文件列表进行获取。
每个功能本身都有效,包括另一个未显示为可进入目录并在其中列出文件的功能。
一天结束时,如果我要走的路很长/错误的话,我只需要我所有github仓库中所有我拥有的package.json文件的内容。
我确实尝试返回一个对象
{
files: files,
paths: paths
}
但是对象每次都是空的。
listRepos = async () => {
const path = '/user/repos'
return fetch(api + path, options)
.then(res => res.json())
.then(json => json.filter(repo => {
return repo.owner.login === user
}))
}
listContents = async (repo) => {
const path = `/repos/${repo.owner.login}/${repo.name}/contents`
return fetch(api + path, options)
.then(res => res.json())
}
getNext = async () => {
let contents = []
let repoList = await listRepos()
return repoList.map(async (repo) => {
await listContents(repo).then(async (contents) => { // This happens for each repo
let pathList = await contents.filter(entry => {
return entry.type === 'dir' && entry.name != 'node_modules'
})
pathList.forEach(path => paths.push(path))
let fileList = await contents.data.filter(entry => {
return entry.name === 'package.json'
})
})
return {
files: fileList,
paths: pathList
}
})
}
我在任意一个之间来回移动
Promise { <pending> }
或“未处理的承诺拒绝”的
我确实意识到我需要抓住我所有的错误,出于空间和可读性的考虑,我从代码中删除了这些错误。
您得到很多Promise { <pending> }
,因为您正在将repoList映射到promises:
return repoList.map(async (repo) => {
异步函数总是返回承诺。您想要这些承诺能够解决的价值。您可以使用Promise.all获取承诺数组的值:
Promise.all([promise, promise]).then(values => console.log(values)
// ['foo', 'bar']
因此,您有一个回购清单,然后将此清单映射到Promise,然后必须将其映射回已解析的值:
const values = await Promise.all(['foo', 'bar'].map(val => fetchSomething(val)))
根据您的情况:
return Promise.all(repoList.map(async (repo) => {
...
}));
[Promise.all
返回一个承诺,所以请记住使用await getNext()
。
在您的repoList映射函数内部,您在listContents映射函数范围内声明了let pathList
和let fileList
,然后尝试从repoList映射函数范围内访问它们。您可能想直接将它们退回,如下所示:
getNext = async () => {
let contents = []
let repoList = await listRepos()
return repoList.map((repo) => {
return listContents(repo).then(async (contents) => { // This happens for each repo
let pathList = await contents.filter(entry => {
return entry.type === 'dir' && entry.name != 'node_modules'
})
pathList.forEach(path => paths.push(path))
let fileList = await contents.data.filter(entry => {
return entry.name === 'package.json'
})
return {
files: fileList,
paths: pathList
}
})
})
}
正如@ezakto已经指出的那样,您的函数将对一个promise数组返回一个promise。加入Promise.all
调用即可获得对结果数组的承诺。通过不使用可以在其中使用async
的then
来简化await
函数(并将await
s放到filter
ed数组上-那里没有异步的对象):
async function getNext() {
let repoList = await listRepos()
return Promise.all(repoList.map(async repo => {
const contents = await listContents(repo);
const pathList = contents.filter(entry => {
return entry.type === 'dir' && entry.name != 'node_modules'
})
// paths.push(...pathList)
const fileList = contents.data.filter(entry => {
return entry.name === 'package.json'
})
return {
files: fileList,
paths: pathList
}
}))
}