Мне нужна помощь с циклом 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"));
Спасибо.
Кроме того, асинхронный обратный вызов .forEach редко работает так, как вы хотите... например, imprimirSchedule(allUserData) все равно будет вызываться до того, как allUserData будет иметь какой-либо контент, даже если вы измените обратный вызов forEach на async....
Избегайте антипаттерна конструктора обещаний в getData!
Кстати, вы звоните listarSchedules() до того, как listarMeusProjetos() заполнится projetosList. Вместо глобальной переменной вы должны вернуть обещание для списка.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема в том, что функция обратного вызова на 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) - по понятным причинам
Вы должны использовать ожидание внутри асинхронной функции. В вашем случае вы можете сопоставить свой список проектов с 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)
}
awaitдействителен только в асинхронной функции, но ваш обратный вызов forEach не определен как асинхронный