我正在从github存储库中获取信息。我想获取该存储库中的请求请求列表,获取与每个请求请求关联的提交列表,然后对于每个提交,我想获取诸如提交的作者,与每个提交相关联的文件数以及每个文件的添加和删除的数量。我正在使用axios和github API来完成此任务。我知道如何使用API,但是promise和async函数使我无法完成任务。我有以下代码:
const axios = require('axios');
var mapOfInformationObjects = new Map();
var listOfCommits = [];
var listOfSHAs = [];
var gitApiPrefix = link I'll use to start fetching data;
var listOfPullRequestDataObjects = [];
var listOfPullRequestNumbers = [];
var mapOfPullNumberToCommits = new Map();
function getAllPullRequests(gitPullRequestApiLink) {
return new Promise((resolve, reject) => {
axios.get(gitPullRequestApiLink).then((response) =>{
listOfPullRequestDataObjects = response['data'];
var k;
for (k = 0; k < listOfPullRequestDataObjects.length; k++){
listOfPullRequestNumbers.push(listOfPullRequestDataObjects[k]['number']);
}
resolve(listOfPullRequestNumbers);
}).catch((error) => {
reject(error);
})
})
}
function getCommitsForEachPullRequestNumber(listOfPRNumbers) {
var j;
for (j = 0; j < listOfPRNumbers.length; j++) {
currPromise = new Promise((resolve, reject) => {
currentGitApiLink = gitApiPrefix + listOfPRNumbers[j] + "/commits";
axios.get(currentGitApiLink).then((response) => {
mapOfPullNumberToCommits.set(listOfPRNumbers[j], response['data']);
resolve("Done with Pull Request Number: " + listOfPRNumbers[j]);
}).catch((error) => {
reject(error);
})
})
}
}
function getListOfCommits(gitCommitApiLink){
return new Promise((resolve, reject) => {
axios.get(gitCommitApiLink).then((response) => {
resolve(response);
}).catch((error) => {
reject(error);
})
})
}
到目前为止,我做了一些我想顺序调用的函数。 首先,我想调用getAllPullRequestNumbers(someLink) 然后我想打电话给getCommitsForEachPullRequestNumber(listofprnumbers) 然后getListOfCommits(anotherLink)
所以看起来像
getAllPullRequestNumbers(someLink)
getCommitsForEachPullRequestNumber(listofprnumbers)
getListOfCommits(anotherlink)
但是出现两个问题: 1)我不确定这是否是调用函数的方式,以便序列中的第一个函数先于另一个函数完成。 2)因为我不熟悉Javascript,所以不确定,尤其是使用getCommitsForEachPullRequestNumber函数,因为您运行循环并在循环的每次迭代中调用axios.get()(如果这是您在内部使用promise的方式)功能。
这将是您完成这两项任务的方式吗?任何帮助深表感谢。谢谢!
答案 0 :(得分:1)
当您可以一起运行多个异步操作(以promise表示)时,如果您想知道它们何时完成,请使用Promise.all()
。您收集了一组承诺并将其传递给Promise.all()
,它将告诉您何时全部完成或何时触发错误。如果全部完成,Promise.all()
将返回一个承诺,该承诺将解析为结果数组(每个异步操作一个)。
在迭代数组以执行一组异步操作时,最好使用.map()
,因为这可以帮助您创建一个并行的Promise数组,您可以将其馈送到Promise.all()
。在getCommitsForEachPullRequestNumber()
中的操作方式如下:
function getCommitsForEachPullRequestNumber(listOfPRNumbers) {
let mapOfPullNumberToCommits = new Map();
return Promise.all(listOfPRNumbers.map(item => {
let currentGitApiLink = gitApiPrefix + item + "/commits";
return axios.get(currentGitApiLink).then(response => {
// put data into the map
mapOfPullNumberToCommits.set(item, response.data);
});
})).then(() => {
// make resolved value be the map we created, now that everything is done
return mapOfPullNumberToCommits;
});
}
// usage:
getCommitsForEachPullRequestNumber(list).then(results => {
console.log(results);
}).catch(err => {
console.log(err);
});
然后,在getListOfCommits()
中,由于axios已经返回了承诺,因此没有理由将其包装在手动创建的承诺中。也就是说,实际上,请考虑一个承诺反模式。相反,只需返回axios已经返回的承诺即可。实际上,将其作为函数可能甚至没有理由,因为人们可以直接使用axios.get()
来达到相同的结果:
function getListOfCommits(gitCommitApiLink){
return axios.get(gitCommitApiLink);
}
然后,在getAllPullRequests()
中,您似乎正在进行一次axios.get()
调用,然后处理结果。可以这样做:
function getAllPullRequests(gitPullRequestApiLink) {
return axios.get(gitPullRequestApiLink).then(response => {
let listOfPullRequestDataObjects = response.data;
return listOfPullRequestDataObjects.map(item => {
return item.number;
});
});
}
现在,如果您要尝试按以下顺序依次执行这三个操作:
getAllPullRequests(someLink)
getCommitsForEachPullRequestNumber(listofprnumbers)
getListOfCommits(anotherlink)
您可以将这三个操作中的承诺链接在一起以对其进行排序:
getAllPullRequests(someLink)
.then(getCommitsForEachPullRequestNumber)
.then(mapOfPullNumberToCommits => {
// not entirely sure what you want to do here, perhaps
// call getListOfCommits on each item in the map?
}).catch(err => {
console.log(err);
});
或者,如果您将此代码放在async
函数中,则可以使用async/awit
:
async function getAllCommits(someLink) {
let pullRequests = await getAllPullRequests(someLink);
let mapOfPullNumberToCommits = await getCommitsForEachPullRequestNumber(pullRequests);
// then use getlistOfCommits() somehow to process mapOfPullNumberToCommits
return finalResults;
}
getAllCommits.then(finalResults => {
console.log(finalResults);
}).catch(err => {
console.log(err);
});
答案 1 :(得分:0)
不如jfriend00解决方案干净, 但是我玩了你的代码,终于奏效了
https://repl.it/@gui3/githubApiPromises
您将在变量listOfCommits
中获得提交列表
我不了解您上一个功能的目的,所以我删除了它