Асинхронное ожидание Javascript зацикливается на выборке

Мне нужна помощь с циклом javascript поверх fetch API. Сначала я звоню, чтобы получить проекты по пользователю и сохранить их в projetosList. Пока здесь работает нормально. Но когда я перебираю projetosList для получения информации о расписании в функции listarSchedules, это не работает.

Javascript кричит мне: SyntaxError: await действует только в асинхронных функциях, асинхронных генераторах и модулях.

Я пробовал все комбинации асинхронного ожидания, кроме правильного :(

let urlProjetos = "https://gitlab.com/api/v4/projects?archived=false&private_token=glpat-xx";
let projetosList = [];

function getData(url) {
    return new Promise((resolve, reject)=>{
        fetch(url)
        .then((resp)=>resp.json())
        .then((data)=>{
            return resolve(data);
        })
    });
}

function imprimirProjetos(allUserData) {
    allUserData.forEach((requestPage)=>{
        requestPage.forEach((requestItem)=>{
            let id_nome = requestItem.id + "#" + requestItem.name; 
            projetosList.push(id_nome);
            console.info(id_nome);
        });
    }); 
}

function listarMeusProjetos() {
    let meuId = 123456;
    let urlMeusProjetos = "https://gitlab.com/api/v4/users/" + meuId  + "/projects?private_token=glpat-xx";
    let userRequests = [];

    userRequests.push(getData(urlMeusProjetos));

    Promise.all(userRequests).then((allUserData)=>{
        imprimirProjetos(allUserData);
    });
}

listarMeusProjetos();


// ULTIL HERE WORKS OK


function imprimirSchedule(allUserData) {
    console.info(allUserData);
}

// PROBLEM!!!!
async function listarSchedules() {
    let userRequest = null;
    let allUserData = [];
    let allPromessas = [];

    projetosList.forEach((item)=>{
        let projetoId   = item.split("#")[0];
        let projetoNome = item.split("#")[1];

        console.info("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
        let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId  + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";

        console.info("urlSchedule");
        console.info(urlSchedule);

        userRequest = (getData(urlSchedule))
        await userRequest.then((data)=>{
            let str = projetoId + "#" + data.description + "#" + data.owner.username;
            allUserData.push(str)
        })

    });

    imprimirSchedule(allUserData)


}

listarSchedules().then(()=>console.info("DONE"));

Спасибо.

await действителен только в асинхронной функции, но ваш обратный вызов forEach не определен как асинхронный
TheMonarch 09.06.2023 01:37

Кроме того, асинхронный обратный вызов .forEach редко работает так, как вы хотите... например, imprimirSchedule(allUserData) все равно будет вызываться до того, как allUserData будет иметь какой-либо контент, даже если вы измените обратный вызов forEach на async....

Jaromanda X 09.06.2023 01:45

Избегайте антипаттерна конструктора обещаний в getData!

Bergi 09.06.2023 04:10

Кстати, вы звоните listarSchedules() до того, как listarMeusProjetos() заполнится projetosList. Вместо глобальной переменной вы должны вернуть обещание для списка.

Bergi 09.06.2023 04:11
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема в том, что функция обратного вызова на projectosList.forEach() не была настроена на асинхронность. Добавление async должно исправить это.

async function listarSchedules() {
    let userRequest = null;
    let allUserData = [];
    let allPromessas = [];

    projetosList.forEach(async (item)=>{
        let projetoId   = item.split("#")[0];
        let projetoNome = item.split("#")[1];

        console.info("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
        let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId  + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";

        console.info("urlSchedule");
        console.info(urlSchedule);

        userRequest = (getData(urlSchedule))
        await userRequest.then((data)=>{
            let str = projetoId + "#" + data.description + "#" + data.owner.username;
            allUserData.push(str)
        })

    });

    imprimirSchedule(allUserData)
}

это не поможет, так как allUserData все равно будет пустым в imprimirSchedule(allUserData) - по понятным причинам

Jaromanda X 09.06.2023 01:40
Ответ принят как подходящий

Вы должны использовать ожидание внутри асинхронной функции. В вашем случае вы можете сопоставить свой список проектов с URL-обещаниями и разрешить его с помощью await.

Рефакторинг вашей проблемной функции:

// PROBLEM!!!!
async function listarSchedules() {
    const allUserData = await Promise.all(projetosList.map(async item => {

        const [projetoId, projetoNome] = item.split("#");

        console.info("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
        let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId  + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";

        console.info("urlSchedule");
        console.info(urlSchedule);

        const {description, owner:{username}} = await getData(urlSchedule);
        return `${projetoId}#${description}#${username}`;

    }));

    imprimirSchedule(allUserData)

}

Другие вопросы по теме