Выборка цепочки, выборка, карта, фильтр, выборка, выборка - PullRequest
0 голосов
/ 29 октября 2019

Чем отличается моя проблема: после того, как я успешно выполнил цепочку обещаний, у меня остались отдельные массивы со списком файлов и каталогов, мне нужно снова извлечь файлы из этих каталогов, добавить их в первый список файлов, а затем, наконец, выбрать на основедля всего заполненного списка файлов.

Каждая функция самостоятельно, включая другую, не показанную для спуска в каталоги и перечисления файлов там, также работает.

В концедень мне просто нужно содержимое любых файлов package.json, которыми я владею, во всех моих репозиториях на github, если я иду по этому длинному / неправильному пути.

Я действительно пытался вернуть объект

{
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> }

или "Отклонением необработанного обещания" 's

Я понимаю, что мне нужно отлавливать все мои ошибки, я вырезал их из кода здесь для простоты и читабельности.

Ответы [ 2 ]

0 голосов
/ 29 октября 2019

Как уже заметил @ezakto, ваша функция возвращает обещание для массива обещаний. Добавьте вызов 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
        }
    }))
}
0 голосов
/ 29 октября 2019

Вы получаете много Promise { <pending> }, потому что вы отображаете свой repoList на обещания:

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

Асинхронные функции всегда возвращают обещание. Вы хотите значения, к которым эти обещания разрешают. Вы можете получить значения массива обещаний, используя Promise.all:

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

Итак, у вас есть список репозиториев, затем вы сопоставляете этот список с обещаниями, затем вы должны сопоставить его с разрешенными значениями. :

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

В вашем случае:

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

Promise.all возвращает обещание, поэтому не забывайте использовать await getNext().


Внутри своего repoListФункция отображения, вы объявляете let pathList и let 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
            }
        })
    })
}
...