So I am working with promises and async/await for the first time. From my understanding async makes a function asynchronous and allows other functions to be executed while it awaits a response from a query etc. We were given the following code as an example and asked to describe in which order it executes:
const axios = require("axios");
const contributorCount = (repositories, contributorsList) => {
let repositoryContributorCount = [];
for (let i = 0; i < repositories.length; i++) {
repositoryContributorCount.push({
name: repositories[i].name,
numberOfContributors: contributorsList[i].length,
});
}
return repositoryContributorCount;
};
const getRepoContributors = async (repo) => {
const contributorsReponse = await axios.get(repo.contributors_url);
return await contributorsReponse.data;
};
const getAllRepos = (repos) => {
const newRepos = repos.slice(0, 5);
return Promise.all(newRepos.map(getRepoContributors)).then((contributors) => {
return contributorCount(newRepos, contributors);
});
};
function listRepoContributorCounts() {
axios
.get("https://api.github.com/orgs/wesabe/repos")
.then((response) => response.data)
.then(getAllRepos)
.then((repositoryContributorCounts) => {
return repositoryContributorCounts;
})
.catch((error) => {
return error;
});
}
By my understanding, in the 2nd function we're assigning an async function to getRepoContributors and that function waits to get a response from the given url. While it's waiting for the response it allows the rest of the code to execute. But why is there a second await for the return statement? Shouldn't you only need the first since the return statement would only execute after the data is retrieved? Also what would be the exact order these functions execute in? 1-4 or 4-1 etc? Really appreciate all the help, promises are the most confusing thing I've ran into in terms of JS so far but I feel like I have decent basic understanding of it. Async/await is complicating things for me further tho
I was also given a 2nd code excerpt which is pretty similar to above and asked to describe the order of execution again.
const axios = require("axios");
const contributorCount = (repositories, contributorsList) => {
return repositories.map((repository, position) => {
return {
name: repository.name,
numberOfContributors: contributorsList[position].length,
};
});
};
const getRepositoryContributors = async (repository) => {
const contributorsResponse = await axios.get(repository.contributors_url);
return await contributorsResponse.data;
};
const getRepositories = (repositories, upToIndex) => {
const repositoriesCopy = repositories.slice(0, upToIndex);
return Promise.all(repositoriesCopy.map(getRepositoryContributors)).then(
(contributors) => {
return contributorCount(repositoriesCopy, contributors);
}
);
};
const getOrganizationInfo = async (organizations) => {
const organizationRepositories = await axios.get(organizations[2].repos_url);
return organizationRepositories.data;
};
function findOrganizationInfo() {
axios
.get("https://api.github.com/organizations")
.then((response) => response.data)
.then(getOrganizationInfo)
.then((repositories) => getRepositories(repositories, 5))
.then((repositoryContributorCounts) => {
console.log(repositoryContributorCounts);
})
.catch((error) => {
console.log(error);
});
}
asyncdoesn't make a function asynchronous. It does two things:Promiseand return that promise; this allows callers to use.then()orawaitto get the result of the function.awaitinside the function.The function is actually asynchronous if it calls other asynchronous functions; in this example,
axios.get()is async.awaitallows you to call an async function that returns a promise as if your code is sequential. But it only makes the code within the calling function sequential-like; the function actually returns the promise immediately, and other code that doesn't wait for it can proceed. This keeps the application from locking up while the async operation is taking place.But since all the code in your example uses either
awaitor.then(), it's mostly sequential within this context.listRepoContributorCounts()callsaxios.get()and uses.then()to wait for its response.After getting the response, it calls
getAllRepos()with the array fromresponse.data.getAllRepos()callsnewRepos.map(getRepoContributors). Each of the calls togetRepoContributors()performs anaxios.get()call, which is asynchronous, and returns its promise. So these AJAX requests run concurrently.Then it calls
Promise.all()on this array of promises, which makes it wait for all of them to complete. The array of values that are returned will be passed to the anonymous functionThis simply combines the array of repos with the returned contributor data.
contributorCount()is an ordinary, synchronous function.This final code:
is totally redundant and unnecessary.