You have a mix of issues going on. For starters, I'd recommend you read this answer How do I return the response from an asynchronous call as it should help you to understand some of the issues with returning a value that was retrieved asynchronously (can only be returned via callback or promise).
Then, I'd suggest using the request-promise library instead of plain http.request()
because it's both higher level (accumulates the entire response for you), will automatically parse to JSON and it supports a promise interface which will be really useful in looping for each page.
Then, we'll use async
and await
to make a loop using asynchronous operations a lot simpler.
And, lastly, you don't show exactly how a loop over all the pages would work, so I'll just give you some pseudo-code for that and you will have to fill in the real implementation for github.
const rp = require('request-promise');
async function getAllCommits(baseURL) {
// init counter
let totalCommits = 0;
// page number counter
let pageNum = 0;
// loop until we break out
while (true) {
// request desired page, auto parse JSON response
try {
// make github request, putting page in query string
// the exact request is pseudo-code here, you have to construct
// the desired URL you need for your specific request
let data = await rp({uri: baseURL, json: true, qs: {page: pageNum++}});
} catch(e) {
// have to decide what to do about an error here (continue, abort, etc..)
// for now, I'll just stop further processing, assuming you've requested
// a page beyond what exists
// But, this needs a more real error handling strategy based on what
// github returns
console.log(e);
if (real error) {
// stops further promising, rejects async promise
throw e;
} else {
// breaks out of while loop
break;
}
}
// now iterate over the data and update the totalCommits variable
}
return totalCommits;
}
// sample usage
getAllCommits("http://somehost/someRepository").then(total => {
console.log(total);
}).catch(e => {
console.log(e);
});
Some things you might not know about the getAllCommits()
implmentation:
- It's an
async
function which always returns a promise and it resolves that promise with whatever value you return from that function.
- If you
throw
in an async
function that will reject the returned promise with the exception value as the rejection reason.
- Only
async
functions can use await
.
await
pauses the internal execution of the function until the promise you are awaiting resolves or rejects.
await
only does something useful when awaiting a promise.
- If the promise you are awaiting resolves successfully, you will get a value from the
await
statement.
- If the promise you are awaiting rejects, it will essentially
throw
and the way to catch that error is to use try/catch
with similar syntax to synchronous exceptions.
- An
async
function pauses it's internal execution for await
statements, but upon the first await
, it immediately returns a promise to the outside world and the outside world continues to run your Javascript. So, an async
function does not pause your whole sequence of execution, just the internals of the async
function.
- This means that the result of an
async
function is a promise and the caller must either use await
on that promise or .then()
on that promise to get the returned result.