首页 > 解决方案 > 链接获取、获取、映射、过滤、获取、获取

问题描述

我的问题有何不同:在我成功链接承诺后,我留下了单独的数组列出文件和目录,需要再次获取这些目录中的文件,将其添加到第一个文件列表中,然后最后根据所有完整的文件列表。

每个函数本身,包括另一个未显示的进入目录并在那里列出文件的函数,都可以工作。

归根结底,我只需要我在所有 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> }

或“未处理的承诺拒绝”

我确实意识到我需要捕获所有错误,为了空间和可读性,我将它们从代码中删除。

标签: node.jspromisereturnfetchchain

解决方案


你得到了很多,Promise { <pending> }因为你将你的 repoList 映射到 promises :

return repoList.map(async (repo) => {

异步函数总是返回一个承诺。你想要那些承诺解决的价值观。您可以使用 Promise.all 获取一系列承诺的值:

Promise.all([promise, promise]).then(values => console.log(values)
// ['foo', 'bar']

因此,您有一个 repos 列表,然后将此列表映射到 Promise,然后您必须将其映射回已解析的值:

const values = await Promise.all(['foo', 'bar'].map(val => fetchSomething(val)))

在你的情况下:

return Promise.all(repoList.map(async (repo) => {
    ...
}));

Promise.all返回一个承诺,所以记得使用await getNext().


在您的 repoList 映射函数中,您声明let pathListlet fileList在 listContents 映射函数范围内,然后尝试从 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
            }
        })
    })
}

推荐阅读