我有两个节点服务调用:一个用于从LDAP组获取组成员,另一个用于获取每个成员的详细信息。每次通话都是非阻塞的回调,因此我遇到的情况是,有时我所记录的记录与为个人检索的详细信息不匹配。
是否有一种聪明的方法来编码以防止竞争条件?有时它可以工作,但通常在我下面的控制台日志中,我迭代的记录与从商店返回的记录不匹配,以获取员工的详细信息。以下是代码:
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();
}
});
答案 0 :(得分:5)
在单线程环境中,比如Javascript(和node.js),你真的没有竞争条件。
相反,您遇到了javascript闭包以及关于变量如何在嵌套函数和循环中工作的误解。
rec
在你Ext.each(records, function(rec, ndx)
中定义,并且在你的回调函数中,你正在利用它的值,假设每次迭代,rec
仍然绑定到执行回调时的值相同。
这是不正确的,相反,rec
的值在执行回调函数时被绑定,而不是在创建函数时(这实质上是闭包的定义)。
所以相反,为了让你按照预期的方式工作,你需要强制rec
在创建过程中被绑定(通过执行类似的操作):注意:语法可能有问题:
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);
在上面的示例中,我们立即执行匿名javascript函数,传入值rec
,该值在创建时被myrec
绑定。匿名函数返回一个函数,该函数具有与回调所期望的相同的签名,当您的回调执行该函数时,它将具有rec
的正确值