Javascript 确保从异步函数序列中获取返回值的任何方法

Javascript 确保从异步函数序列中获取返回值的任何方法,javascript,asynchronous,axios,Javascript,Asynchronous,Axios,我正在处理回购协议,并试图获取回购协议的请求、问题和提交。我有以下代码: const axios = require('axios'); var gitPullApiLink = "https://api.github.com/repos/alirezadir/Production-Level-Deep-Learning/pulls" var listOfCommits = []; var listOfSHAs = []; var mapOfInfoObjects = new Map(); va

我正在处理回购协议,并试图获取回购协议的请求、问题和提交。我有以下代码:

const axios = require('axios');
var gitPullApiLink = "https://api.github.com/repos/alirezadir/Production-Level-Deep-Learning/pulls"
var listOfCommits = [];
var listOfSHAs = [];
var mapOfInfoObjects = new Map();
var mapPullRequestNumberToCommits = new Map();
var mapPRNumbersToCommitObjects = new Map();
var listOfPrObjects = [];
var setOfFileObjects = new Set();
var listOfNumbersOfTargetedIssues = [];
 var mapPRnumberToCloseOpenDateObjects = new Map();


class PullRequestParser {

async getListOfPullRequests(pullrequestLink) {
    const message = await axios.get(pullrequestLink);
    //console.log(message);
    listOfPrObjects = message['data'];
}

async getCommitsForEachPullRequestAndPRinformation() {
    var listOfPrNumbers = [];
    var k;
    // this loop will just make a list of Pull Request Numbers
    for (k = 0; k < listOfPrObjects.length; k++){
        var currPrNumber = listOfPrObjects[k]['number'];
        listOfPrNumbers.push(currPrNumber);
    }
    // I created a separate list just because... I did it this way because on the github API website it seems
    // like the pull request has the same number as the issue it affects. I explain how you can see this down below
    listOfNumbersOfTargetedIssues = listOfPrNumbers;
    // next loop will make objects that contain information about each pull request.
    var n;
    for (n = 0; n < listOfPrNumbers; n++){
        var ApiLinkForEachPullRequest = gitPullApiLink + "/" + listOfPrNumbers[n];
        const mes = await axios.get(ApiLinkForEachPullRequest);
        var temp = {OpeningDate: mes['data']['created_at'],
            ClosingDate: mes['data']['closed_at'],
            IssueLink: mes['data']['_links']['issue']['href']};
        //mapPRnumberToCloseOpenDateObjects will be a map where the key is the pull request number and the value
        // is the object that stores the open date, close date, and issue link for that pull request. The reason
        // why I said I think the pull request number is the same as the number of the issue it affects is because
        // if you take any object from the map, say you do mapPRnumberToCloseOpenDateObjects.get(10). You'll
        // get an object with a pull request number 10. Now if you take this object and look at it's "IssueLink"
        // field, the very last part of the link will have the number 10, and if you look at the github API
        // it says for a single issue, you do: /repos/:owner/:repo/issues/:issue_number <---- As you can see,
        // the IssueLink field will have this structure and in place of the issue_number, the field will be 10
        // for our example object.
        mapPRnumberToCloseOpenDateObjects.set(listOfPrNumbers[n], temp);
    }
    //up to this point, we have the pull request numbers. we will now start getting the commits associated with
    //each pull request
    var j;
    for (j = 0; j < listOfPrNumbers.length; j++){
        var currentApiLink = gitPullApiLink + "/" + listOfPrNumbers[j] + "/commits";
        const res = await axios.get(currentApiLink);
        //here we map a single pull request to the information containing the commits. I'll just warn you in
        // advance: there's another object called mapPRNumbersToCommitObjects. THIS MAP IS DIFFERENT! I know it's
        // subtle, but I hope the language can make the distinction: mapPullRequestNumberToCommits will just
        // map a pull request number to some data about the commits it's linked to. In contrast,
        // mapPRNumbersToCommitObjects will be the map that actually maps pull request numbers to objects
        // containing information about the commits a pull request is associated with!
        mapPullRequestNumberToCommits.set(listOfPrNumbers[j], res['data']);
    }
    // console.log("hewoihoiewa");
}

async createCommitObjects(){
    var x;
    // the initial loop using x will loop over all pull requests and get the associated commits
    for (x = 0; x < listOfPrObjects.length; x++){
        //here we will get the commits
        var currCommitObjects = mapPullRequestNumberToCommits.get(listOfPrObjects[x]['number']);
        //console.log('dhsiu');
        // the loop using y will iterate over all commits that we get from a single pull request
        var y;
        for (y = 0; y < currCommitObjects.length; y++){

            var currentSHA = currCommitObjects[y]['sha'];
            listOfSHAs.push(currentSHA);
            var currApiLink = "https://api.github.com/repos/alirezadir/Production-Level-Deep-Learning/commits/" + currentSHA;
            const response = await axios.get(currApiLink);
            //console.log("up to here");
            // here we start extracting some information from a single commit
            var currentAuthorName = response['data']['commit']['committer']['name'];
            var currentDate = response['data']['commit']['committer']['date'];
            var currentFiles = response['data']['files'];
            // this loop will iterate over all changed files for a single commit. Remember, every commit has a list
            // of changed files, so this loop will iterate over all those files, get the necessary information
            // from those files.
            var z;
            // we create this temporary list of file objects because for every file, we want to make an object
            // that will store the necessary information for that one file. after we store all the objects for
            // each file, we will add this list of file objects as a field for our bigger commit object (see down below)
            var tempListOfFileObjects = [];
            for (z = 0; z < currentFiles.length; z++){
                var fileInConsideration = currentFiles[z];
                var nameOfFile = fileInConsideration['filename'];
                var numberOfAdditions = fileInConsideration['additions'];
                var numberOfDeletions = fileInConsideration['deletions'];
                var totalNumberOfChangesToFile = fileInConsideration['changes'];
                //console.log("with file");
                var tempFileObject = {fileName: nameOfFile, totalAdditions: numberOfAdditions,
                    totalDeletions: numberOfDeletions, numberOfChanges: totalNumberOfChangesToFile};
                // we add the same file objects to both a temporary, local list and a global set. Don't be tripped
                // up by this; they're doing the same thing!
                setOfFileObjects.add(tempFileObject);
                tempListOfFileObjects.push(tempFileObject);
            }
            // here we make an object that stores information for a single commit. sha, authorName, date are single
            // values, but files will be a list of file objects and these file objects will store further information
            // for each file.
            var tempObj = {sha: currentSHA, authorName: currentAuthorName, date: currentDate, files: tempListOfFileObjects};
            var currPrNumber = listOfPrObjects[x]['number'];

            console.log(currPrNumber);
            // here we will make a single pull request number to an object that will contain all the information for
            // every single commit associated with that pull request. So for every pull request, it will map to a list
            // of objects where each object stores information about a commit associated with the pull request.
            mapPRNumbersToCommitObjects.set(currPrNumber, tempObj);
        }
    }
    return mapPRNumbersToCommitObjects;
}

startParsingPullRequests() {
    this.getListOfPullRequests(gitPullApiLink  + "?state=all").then(() => {
        this.getCommitsForEachPullRequestAndPRinformation().then(() => {
            this.createCommitObjects().then((response) => {
                console.log("functions were successful");
                return mapPRNumbersToCommitObjects;
            }).catch((error) => {
                console.log("printing first error");
                console.log(error);
            })
        }).catch((error2) => {
            console.log("printing the second error");
            console.log(error2);
        })
    }).catch((error3) => {
        console.log("printing the third error");
        console.log(error3);
    });
}

//adding some getter methods so they can be used to work with whatever information people may need.
//I start all of them with the this.startParsingPullRequests() method because by calling that method it gets all
// the information for the global variables.

async getSetOfFileObjects(){
    var dummyMap = this.startParsingPullRequests();
    return setOfFileObjects;
}

async OpenCloseDateObjects(){
    var dummyMap = this.startParsingPullRequests();
    return mapPRnumberToCloseOpenDateObjects;
}

async getNumbersOfTargetedIssues(){
    var dummyMap = this.startParsingPullRequests();
    return listOfNumbersOfTargetedIssues;
}

}
但我最终得到以下输出:

undefined
3
1
functions were successful

我知道dummyMap是未定义的,因为startParsingPullRequests()会进行一系列异步调用,但我想知道如何确保dummyMap获得其值,然后打印。谢谢

既然您已经有了使用
async
/
wait
的代码,为什么要更改为
。那么
?当你使用
.then
/
.catch
时,你很难分辨事物在等待什么,它们在等待什么

这是转换为使用
async
/
wait
的函数。通过此更改,您可以
等待
此函数(尽管在这种情况下,您可能不希望捕获错误并让调用者处理它,否则您需要检查
未定义
的返回以“检测”错误)。我还简化了错误处理(但同样,除非这里的代码可以“修复”问题,否则没有理由在这里处理它)

async startParsingPullRequests(){
试一试{
等待此消息。getListOfPullRequests(gitPullApiLink+“?state=all”);
等待此消息;
const response=wait this.createCommitObjects();
log(“函数成功”);
将MapPrNumbers返回到CommitObject;
}捕获(错误){
控制台日志(“打印错误”);
console.log(错误);
}

}
任何需要等待的
async
代码都需要在
wait
之后或
子句内部。在这种情况下,
startParsingPullRequests
需要返回一个
Promise
await
代码,然后调用者需要
await
。然后在使用解析的数据之前执行它。在startParsingPullRequests()方法中,我将所有异步方法放在.then子句中,但即使我试着说:var dummymmap=wait dummy.startParsingPullRequests();甚至类似于:var dummymmap=dummy.startParsingPullRequests()。然后(…)它仍然不起作用
startParsingPullRequests
返回未定义的。没有什么可等待的
。您需要返回一个
Promise
(所有
。然后
链返回承诺,所以您只需要返回它)=>
返回这个。getListOfPullRequests(gitpullaplink+“?state=all”)。然后(()=>{
您可能还会发现,在
startParsingPullRequests
中使用
async
/
wait
更容易遵循。您的
.catch
需要更改为
try
/
catch
,否则代码流应该更容易遵循。
undefined
3
1
functions were successful