从客户端调用node.js服务时的竞争条件

occ*_*asl 1 javascript asynchronous node.js

我有两个节点服务调用:一个用于从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();
        }
    });
Run Code Online (Sandbox Code Playgroud)

Ala*_*lan 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);
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我们立即执行一个匿名的javascript函数,传入在创建时rec受到约束的值myrec.匿名函数返回一个函数,该函数具有与回调所期望的相同的签名,并且当您的回调执行该函数时,它将具有适当的值rec