I'm utilizing an async approach to an iteration in order to call several AJAX requests for each object inside an array called rsPatients
(i.e., I use an if
conditional instead of a for
loop), and inside this iteration is a chained Promise
.
function BuildBoardTable() {
var objLength = Object.keys(rsPatients).length
if (objLength === 0) {
$('#tblMessageData').html('<tr style="vertical-align:top;"><td style="background-color:#EEE;" colspan="8">No Patients</td></tr>');
return false;
}
var phoneNumber;
var rsDevice;
var counter = 0;
getExternalData();
function getExternalData() {
if (counter < objLength) {
var CaseNumber = rsPatients[counter].CaseNo;
var Loc_Code = rsPatients[counter].LocationCode;
getPhoneNumber(CaseNumber, Loc_Code).then(function () {
console.log(counter);
console.log('get1'); //[breakpoint #1]
}).then(function () {
getDeviceData(CaseNumber, Loc_Code); //[breakpoint #2]
}).then(function () {
console.log('get2'); //[breakpoint #4]
}).then(function () {
console.log('get3'); //[breakpoint #5]
counter++;
}).finally(function () {
getExternalData(); //[breakpoint #6]
});
} else {
counter = 0;
$('#content-holder > .appwait').hide();
}
}
function getPhoneNumber(CaseNumber, Loc_Code) {
return new Promise(function (resolve, reject) {
$.ajax({
type: 'GET',
url: 'api/Phone/PatientNumber',
data: {
'case_no': CaseNumber,
'loc_code': Loc_Code
},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
phoneNumber = result.Number;
console.log(result.Number);
resolve(result);
},
failure: function (xhr, status, error) {
console.log(xhr + ", " + status + ": " + error);
alert(xhr + ", " + status + ": " + error);
phoneNumber = '';
reject(error);
}
});
});
}
function getDeviceData(CaseNumber, Loc_Code) {
$.ajax({
type: 'GET',
url: 'api/Phone/PatientDevice',
data: {
'case_no': CaseNumber,
'loc_code': Loc_Code
},
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
rsDevice = result;
console.log(result); //[breakpoint #3]
},
failure: function (xhr, status, error) {
console.log(xhr + ", " + status + ": " + error);
alert(xhr + ", " + status + ": " + error);
rsDevice = null;
}
});
}
}
What I expect the console to read like (replacing actual phone numbers & device data with placeholders, of course):
555-555-5555
0
get1
{ApplicationCode: '', LDID: 0, LoanerID: ''}
get2
get3
555-555-5555
0
get1
{ApplicationCode: '', LDID: 0, LoanerID: ''}
get2
get3
555-555-5555
0
get1
{ApplicationCode: '', LDID: 0, LoanerID: ''}
get2
get3
. . .
What I actually see:
555-555-5555
0
get1
get2
get3
555-555-5555
1
get1
get2
get3
{ApplicationCode: '', LDID: 0, LoanerID: ''}
555-555-5555
2
get2
get3
{ApplicationCode: '', LDID: 0, LoanerID: ''}
{ApplicationCode: '', LDID: 0, LoanerID: ''}
555-555-5555
3
get1
get2
{ApplicationCode: '', LDID: 0, LoanerID: ''}
. . .
When running the application in Debug Mode in Visual Studio, it hits the breakpoints in the following order: 1, 2, 4, 5, 6, 3. If I move breakpoint #3 to the line above, rsDevice = result;
, it's the same order.
Why is getDeviceData
finishing last in the Promise chain? Or, at the very least, finishing at its own pace from the rest? This will affect which device data is applied to which patient/case number, and obviously we don't want a mismatch to occur here.