从客户端调用node.js服务时的Race Condition

我有两个节点服务调用:一个是从LDAP组中获取组成员,另一个是获取每个成员的详细信息。 每个调用都是非阻塞的,所以我遇到了一种情况,即有时候我logging的logging与个人检索的细节不匹配。

有没有一个聪明的方法来编码,以防止竞争条件? 有时候它可以正常工作,但是经常在我正在执行下面的控制台日志的行上,我正在迭代的logging与从商店返回的logging不匹配以获取员工详细信息。 这里看看代码:

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(); } }); 

在一个单线程的环境中,比如Javascript(和node.js),你不可能有竞争条件。

相反,你正在运行的JavaScriptclosures和误解,如何variables在嵌套函数和循环工作。

rec是在你的Ext.each(records, function(rec, ndx)和你的callback函数里面定义的,你正在使用它的值,假设对于每次迭代, rec仍然绑定到相同的值callback被执行。

这是不正确的,而rec的值是在执行callback函数的时候绑定的,而不是在创build函数的时候(这本质上就是闭包的定义)。

所以相反,要按照您期望的方式工作,您需要通过执行类似的操作(注意:语法可能有问题)来强制rec在创build过程中被绑定:

 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函数,在创build的时候myrecmyrec绑定的值rec 。 匿名函数返回一个与callback期望的签名相同的函数,当你的callback执行函数时,它将具有适当的rec