Axios forEach请求,获得响应并将其添加到数组中



我有一个函数,它需要一个数组的GitHub存储库名称,然后我想发送一个请求与每个存储库,获得关于使用的语言在这个存储库的数据,并将其添加到一个数组。它看起来像这样:

function getRepositoryLanguages(owner, repos) {
var stats = [];
repos.forEach(async (repoName) => {
try {
repoLang = await axios.get(
`https://api.github.com/repos/${owner}/${repoName}/languages`,
{
headers: {
Authorization: "token ${token}",
},
}
);
stats.push(repoLang.data, repoName);
} catch (error) {
console.log(error);
}
});
return stats;
}

我想获得每个存储库的语言统计信息,然后将其存储在称为stats的数组中。问题是这个函数返回一个空数组,当我这样做的时候:

getRepositoryNames(username).then((repos) => {
console.log(getRepositoryLanguages(username, repos));
});

我刚得到一个[]

有没有人知道如何正确地编写这个函数,并记住这些函数将在app.get(/stats)路由中使用?

.forEach不玩异步行为,它期望一个同步函数(见这里)。

相反,请确保您的getRepositoryLanguages函数是async,并使用更简单的迭代器,例如标准的for.. of..循环。

代码示例如下:

const doSomethingAsync = (repoName) => {
return new Promise(resolve => setTimeout(resolve(repoName+'Lang'), 100));
}
const getRepositoryLanguages = async (owner, repos) => {
let stats = []
for (const repoName of repos) {
const repoLang = await doSomethingAsync(repoName)
stats.push(repoLang)
}
return stats
}
const init = async () => {
const data = await getRepositoryLanguages('username', ['repo1','repo2'])
console.log('data', data)
}
init()

如果你不担心速率限制,并且想并行做一些事情,你可以像这样Promise.all:

const doSomethingAsync = (repoName) => {
console.log('doSomethingAsync START', repoName)
return new Promise(resolve => setTimeout(() => {
console.log('doSomethingAsync END', repoName)
resolve(repoName + 'Lang')
}, 1000));
}
const getRepositoryLanguages = async(owner, repos) => {
const stats = await Promise.all(repos.map(async(repoName) => {
return doSomethingAsync(repoName)
}))
return stats
}
const init = async() => {
const data = await getRepositoryLanguages('username', ['repo1', 'repo2'])
console.log('data', data)
}
init()

第一条信息:

ForEach 循环不会停止循环的执行,即使其中有async/await操作->将其转换为普通的For Loopfor(let I = 0 ....)

/**
* 
* @param owner Owner of repository
* @param repos All his public repos
* @returns Language statistics
*/
async function getRepositoryLanguages(owner, repos) {
/**
* language statistics
*/
let stats = [];
for (let index = 0; index < repos.length; index++) {
const repoName = repos[index];
const response = await axios.get(
`https://api.github.com/repos/${owner}/${repoName}/languages`, {
headers: {
Authorization: "token ${token}",
},
}
)
stats.push({
name: repoName,
languages: response.data
});
};
return stats;
}
getRepositoryNames(username).then(async(repos) => {
console.log(await getRepositoryLanguages(username, repos));
});

最新更新