Some ideas to refactor the code using promises.
a promisified XMLHttpRequest request function getRepLink
that performs one request. It rejects for request errors and HTTP errors (not "200" status).
a promisifed getSetOfRecords
function to get a single response, parse it as JSON data and extract the link header value. It rejects iff there are no records.
a promisified process records function which tries to process a given number of records in sets. It fulfills with the number of records processed. It ignores the no records error if some records have already been processed.
// XMLHttp request
function getRepoLink (repUrlLink) {
return new Promise( function (resolve, reject) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open('GET', repoUrlLink, false);
xmlHttp.setRequestHeader('Authorization', 'Bearer ' + userData.accessToken);
xmlHttp.onload = function () {
if( xmlHttp.status == 200) {
resolve( xmlHttp);
}
else {
reject( new Error("HTTP error " + xmlHttp.status));
}
};
xmlHttp.onerror = reject;
xmlHttp.send();
});
}
// get a set of records
const EndOfRecords = new Error( "End of Records");
function getSetOfRecords( repUrlLink) {
return getRepoLink( repUrlLink).then(
function( xmlHttp) {
var result = JSON.parse(xmlHttp.responseText);
if (result.length == 0) {
displayNoRecordsMessage();
throw EndOfRecords; // reject the returned promise
}
var header = xmlHttp.getResponseHeader('link');
return {result, header}; // fulfill the returned promise
}
);
}
// get up to `count` records and process them
function processRecords( repUrlLink, count) {
var processed = 0;
function processSomeMore() {
return getSetOfRecords().then( function ({result, header}) {
$.each(result, function (index, eachData) {
// do something with data
processed++;
});
if( header) {
//do something with header
if( processed < count)
return processSomeMore() // asynchronous "recursion"
}
else {
// do as required if no link header present.
}
return processed; // fulfill returned promise
},
function( error) {
if( error === EndOfRecords && processed > 0) {
return processed; // got some records
};
throw error; // reject returned promise
});
}
return processSomeMore();
}
// Start asynchronous operation
processRecords( repUrlLink, 90)
.then( processed => console.log( processed + " records processed"))
.catch( error => console.log( error));