1

2つのノードサービス呼び出しがあります。1つはLDAPグループからグループメンバーを取得するためのもので、もう1つは各メンバーの詳細を取得するためのものです。各呼び出しはコールバックで非ブロッキングであるため、私が使用しているレコードが個人に対して取得された詳細と一致しない場合があります。

競合状態を防ぐためにこれをコーディングする賢い方法はありますか?動作する場合もありますが、以下のコンソールログを実行している行では、反復しているレコードが、従業員の詳細を取得するためにストアから返されたレコードと一致しないことがよくあります。コードを見てみましょう。

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

1 に答える 1

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

于 2012-12-17T22:38:05.177 に答える