英文:
Javascript async await looping over fetch
问题
我需要一些关于JavaScript循环处理Fetch API的帮助。
首先,我发起一个调用以获取用户的项目并将它们存储在projetosList
中。
到这里都没问题。
但是当我在listarSchedules
函数中循环遍历projetosList
以获取计划信息时,它不起作用。
JavaScript向我抛出错误:SyntaxError: await is only valid in async functions, async generators and modules.
我尝试了除了正确的组合之外的所有async-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.log(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();
// 到这里都正常
function imprimirSchedule(allUserData) {
console.log(allUserData);
}
// 问题发生在这里!!!
async function listarSchedules() {
let userRequest = null;
let allUserData = [];
let allPromessas = [];
projetosList.forEach((item)=>{
let projetoId = item.split("#")[0];
let projetoNome = item.split("#")[1];
console.log("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";
console.log("urlSchedule");
console.log(urlSchedule);
userRequest = (getData(urlSchedule))
await userRequest.then((data)=>{
let str = projetoId + "#" + data.description + "#" + data.owner.username;
allUserData.push(str)
})
});
imprimirSchedule(allUserData)
}
listarSchedules().then(()=>console.log("DONE"));
谢谢。
英文:
I need some help with javascript loop over fetch api.
First I make a call to get projects by user and store then in projetosList
.
Until here works fine.
But when I loop over projetosList
to fetch schedules info in listarSchedules
function, doesn't works.
Javascript shouts out to me: SyntaxError: await is only valid in async functions, async generators and modules.
I've tried every combination of async-wait except the correct one
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.log(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.log(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.log("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";
console.log("urlSchedule");
console.log(urlSchedule);
userRequest = (getData(urlSchedule))
await userRequest.then((data)=>{
let str = projetoId + "#" + data.description + "#" + data.owner.username;
allUserData.push(str)
})
});
imprimirSchedule(allUserData)
}
listarSchedules().then(()=>console.log("DONE"));
Thanks.
答案1
得分: 1
你应该在异步函数内部使用await
。在你的情况下,你可以将项目列表映射到URL的Promise,并使用await
解析它。
重构你有问题的函数:
// 问题所在!!!
async function listarSchedules() {
const allUserData = await Promise.all(projetosList.map(async item => {
const [projetoId, projetoNome] = item.split("#");
console.log("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";
console.log("urlSchedule");
console.log(urlSchedule);
const {description, owner:{username}} = await getData(urlSchedule);
return `${projetoId}#${description}#${username}`;
}));
imprimirSchedule(allUserData)
}
希望对你有所帮助!
英文:
You should use an await inside an async function. In your case you can map your project list to url promises, and resolve it with await
.
Refactored you problematic function:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
// PROBLEM!!!!
async function listarSchedules() {
const allUserData = await Promise.all(projetosList.map(async item => {
const [projetoId, projetoNome] = item.split("#");
console.log("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";
console.log("urlSchedule");
console.log(urlSchedule);
const {description, owner:{username}} = await getData(urlSchedule);
return `${projetoId}#${description}#${username}`;
}));
imprimirSchedule(allUserData)
}
<!-- end snippet -->
答案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.log("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";
console.log("urlSchedule");
console.log(urlSchedule);
userRequest = getData(urlSchedule);
await userRequest.then((data) => {
let str = projetoId + "#" + data.description + "#" + data.owner.username;
allUserData.push(str);
});
});
imprimirSchedule(allUserData);
}
请注意,代码中的注释和变量名保持不变。
英文:
The problem is that the callback function on the projectosList.forEach()
was not set to asynchronous. Adding async
like this should fix it
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.log("PROJETO ID: " + projetoId + " PROJETO NOME: " + projetoNome);
let urlSchedule = "https://gitlab.com/api/v4/projects/" + projetoId + "/pipeline_schedules?private_token=glpat-uSjCXDMEZPh5x6fChMxs";
console.log("urlSchedule");
console.log(urlSchedule);
userRequest = (getData(urlSchedule))
await userRequest.then((data)=>{
let str = projetoId + "#" + data.description + "#" + data.owner.username;
allUserData.push(str)
})
});
imprimirSchedule(allUserData)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论