Chaining fetch,fetch,map,filter,fetch,fetch

问题描述 投票:0回答:2

我的问题与众不同:成功链接诺言后,我剩下列出文件和目录的单独数组,需要再次获取这些目录中的文件,将其添加到第一个文件列表中,最后根据所有已完成的文件列表进行获取。

每个功能本身都有效,包括另一个未显示为可进入目录并在其中列出文件的功能。

一天结束时,如果我要走的路很长/错误的话,我只需要我所有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.js promise return fetch chain
2个回答
0
投票

您得到很多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 pathListlet 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
            }
        })
    })
}

0
投票

正如@ezakto已经指出的那样,您的函数将对一个promise数组返回一个promise。加入Promise.all调用即可获得对结果数组的承诺。通过不使用可以在其中使用asyncthen来简化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
        }
    }))
}
© www.soinside.com 2019 - 2024. All rights reserved.