I have two node service calls I make: one to get the group members from an LDAP group and the other to get each members details. Each call is non-blocking with callbacks so I'm running into a situation where sometimes the record I'm on isn't matching up with the details retrieved for the individual.
Is there a clever way to code this to prevent the race condition? Sometimes it works but often on the line where I'm doing the console log below, the record I'm iterating on is not matched up with the one returned from the store to get the employee details. Here's a look at the code:
onGroupSelected: function (list, idx, el, record) {
var store = Ext.getStore('GroupMembers');
store.getProxy().setUrl('http://people-nodejs.xxx.xxx.com/ldap/group/' + record.get('cn'));
var that = this;
store.load({
callback: function (records, operation) {
var empstore = Ext.getStore('EmployeeDetails');
Ext.each(records, function(rec, ndx) {
console.log(ndx + ":" + rec.get('memberUid'));
if (rec.get('isMember')) {
empstore.getProxy().setUrl('http://people-nodejs.xxx.xxx.com/ldap/user/' + rec.get('memberUid'));
empstore.load({
callback: function(emps, op) {
console.log(ndx + ":" + rec.get('memberUid') + "--" + emps[0].get('fullName'));
rec.set('workforceID', emps[0].get('workforceID'));
rec.set('fullName', emps[0].get('fullName'));
that.getGroupMembersList().setRecord(rec);
}
});
}
});
// Remove empty records and populate with records from above
store.removeAll();
}
});
In a single threaded environment, like Javascript (and node.js), you can't really have race conditions.
Instead you are running into javascript closures and a misunderstanding as to how variables work in nested functions and loops.
rec is defined inside you Ext.each(records, function(rec, ndx), and inside your callback function, you are making use of it's value, with the assumption that for each iteration, rec is still bound to the same value when when the callback was executed.
This is incorrect, and instead the value of rec is bound at the time the callback function is executed, not at the time the function is created (this is, in essence, the definition of a closure).
So instead for this to work the way you expect, you will need to force rec to be bound during creation, by doing something like (note: syntax may have issues):
callback: (function(myrec,index){
return function(emps, op) {
console.log(index + ":" + myrec.get('memberUid') + "--" + emps[0].get('fullName'));
myrec.set('workforceID', emps[0].get('workforceID'));
myrec.set('fullName', emps[0].get('fullName'));
that.getGroupMembersList().setRecord(myrec);
};)(rec,ndx);
In the example above, we're executing an anonymous javascript function immediately, passing in the value rec which gets bound by myrec at creation time. The anonymous function returns a function with the same signature that the callback expects, and when your callback executes the function, it will have the proper value for rec