如何处理访问javascript中数据结构的两个回调?

如何处理访问javascript中数据结构的两个回调?,javascript,concurrency,callback,firebase,Javascript,Concurrency,Callback,Firebase,更新2: 我认为这是一个更好的解释: 我有两个回调,每个回调都填充了一个数组。我想以某种方式合并这些数组。最简单的方法是等待数组被填充,然后用for循环合并。我不能这样做,因为没有真正的方法来检查回调是否“完成” 下一步可能是这样的:每次回调下载对象时,它都会检查合并数组(称为mixed),并查看它是否包含“partner”对象。如果是:则合并到该伙伴对象中。如果没有,则插入该对象 我担心竞争条件:回调1看到数组为空,决定插入数组,但随后控制切换到回调2,回调2首先插入数组。回调1现在应该合并而

更新2: 我认为这是一个更好的解释:

我有两个回调,每个回调都填充了一个数组。我想以某种方式合并这些数组。最简单的方法是等待数组被填充,然后用for循环合并。我不能这样做,因为没有真正的方法来检查回调是否“完成”

下一步可能是这样的:每次回调下载对象时,它都会检查合并数组(称为mixed),并查看它是否包含“partner”对象。如果是:则合并到该伙伴对象中。如果没有,则插入该对象

我担心竞争条件:回调1看到数组为空,决定插入数组,但随后控制切换到回调2,回调2首先插入数组。回调1现在应该合并而不是插入,但当控件切换回时,它将插入

如果我能做一个原子的“检查和插入/合并”代码块,那会有所帮助。有办法吗


更新1: 现在有了代码,还有更多的单词

谢谢大家的回复。我试着尽可能地简化代码

单词:

我有一个名为mixed的数组。混合后的结果应该是:所有类型(A)的对象,如果它们有类型(B)的模拟对象(也称为“私有对象”),则应该合并它们

这意味着使用两个使用回调的函数——getAllA和getAllB。现在,我调用这两个函数,手动稍等,然后运行一个for循环来进行合并

我需要做的是编辑代码,以便在回调中进行合并。然而,我想不出一种不创造比赛条件的合并方式

天真地说,我可能希望首先填充混合了A类型的对象,然后遍历B对象并根据需要合并它们。但是,我不能这样做,因为无法查看您是否在firebase中“完成”了on(“添加了联系人”)。我想我想要的是一个并发数组结构,但我不知道如何使用内置数组结构。我担心自己会犯错,因为我不知道如何检查自己是否做错了。比赛条件就是这样

现在,代码: 以下是您需要参考的脚本:

下面是我粘贴到javascript控制台中的内容:

    //Note: private ~~ B
    //      public ~ A

    var me = 'IWwypRHWpDmydd30o-v';
    var mixed = new Array();
    var mixedNames = new Array();
    var privates = new Object();

    var callbackB = function(snapshot){
        child = snapshot.val();
        privates[snapshot.name()] = child;
    };

    var callbackA = function(snapshot){
        var listRef = snapshot.ref();
        listRef.on('child_added', function (snapshot2) {
        child = snapshot2.val();
            mixedNames.push(snapshot2.name());
            mixed.push(child);
      });
    };

    var getAllB = function (callback, ownerid){
        var priv = new Firebase('http://gamma.firebase.com/innermost/project/private/' + ownerid);
        priv.on('child_added', function (snapshot){
        callback(snapshot);
      });
    };

    function getAllA(callback) {
      var pub = new Firebase('http://gamma.firebase.com/innermost/project/public');
      pub.once('value', function (snapshot) {
        if (snapshot.val() === null) {
          alert('snapshot does not exist.');
        }
        callback(snapshot);
      });
    }

    getAllA(callbackA);
    getAllB(callbackB, me);

    //////wait

    for (b in privates){
        var index = $.inArray(b, mixedNames);
        if (index < 0){ //if there is no record with this name
            mixed.push(privates[b]);
            mixedNames.push(b);
        }
        else{
            var pub = mixed[index];
            var mutt = returnMixed(pub, privates[b]);
            mixed.splice(index,1,mutt);
        }
    };
//注意:private~~B
//公共~A
变量me='IWYPRHWPDMYDD30O-v';
var mixed=新数组();
var mixedNames=新数组();
var privates=新对象();
var callbackB=函数(快照){
child=snapshot.val();
privates[snapshot.name()]=child;
};
var callbackA=函数(快照){
var listRef=snapshot.ref();
listRef.on('child_added',函数(快照2){
child=snapshot2.val();
mixedNames.push(snapshot2.name());
混合。推(儿童);
});
};
var getAllB=函数(回调,ownerid){
var priv=新的Firebase('http://gamma.firebase.com/innermost/project/private/“+所有者ID);
priv.on('添加子项',功能(快照){
回调(快照);
});
};
函数getAllA(回调){
var pub=新Firebase('http://gamma.firebase.com/innermost/project/public');
发布一次('value',函数(快照){
if(snapshot.val()==null){
警报('快照不存在');
}
回调(快照);
});
}
盖塔拉(callbackA);
getAllB(callbackB,me);
//////等等
(b)私家车{
var索引=$.inArray(b,混合名称);
if(index<0){//如果没有具有此名称的记录
混合。推(私人[b]);
混合名称。推送(b);
}
否则{
var pub=混合[指数];
var mutt=returnMixed(公共、私人[b]);
混合拼接(指数1,mutt);
}
};
我想做的是将逻辑从for循环移动到回调中,因为如果您立即运行for循环,那么还不能通过回调下载数组


旧条目:

我有两个回调访问Firebase上的数据列表

回调1获取类型为A的对象。 回调2获取类型为B的对象

我的目标是创建一个数组,该数组可以正确地合并A和B类型的对象

大多数(但必须是所有)类型B的对象都有一个类型a的“partner”对象。 少数类型为A的对象具有类型为B的伙伴对象

对于从Firebase提取的每个对象,我想看看它们的伙伴是否在阵列中。如果没有,则插入。如果是,则改为与合作伙伴“合并”

我想不出一种没有并发数据结构的方法来实现这一点,但我不知道如何在Javascript中实现这一点


我怎样才能创建那个并发数组,或者找到一种方法来实现我的目标呢?

JS的值为零,对吗?无论如何,如果他们不这样做,这个答案是无用的

我要做的是在主数组上有一个函数,传递一个对象,检查它的伙伴是否在数组中。如果是,则返回所述对象,否则返回nil。这样,如果需要,您已经有了要执行合并的对象


此外,从您的措辞来看,我不太确定,但您似乎担心并发性会成为一个问题(竞争条件、覆盖等)?如果是这样的话,这是一个使用互斥锁的完美例子(如果js还没有互斥锁,你可以很容易地创建自己的互斥锁)。只要使用上面提到的函数,在开始时锁定,在结束时解锁,就可以避免读取过期数据。希望有帮助。

JS的值为零,对吗?无论如何,如果他们不这样做,这个答案是无用的

我要做的是在主数组上有一个函数,你可以传递一个对象,然后检查它的伙伴是否
<script src="underscore.js"></script> <!-- or the lib of your choice -->
<script>

   function addWithPartner( value, id, type ) {
      var indexOfPartner = _.find(values, function(partner, i) {
         // logic for determining what a partner is goes here
         // for example: 
         return value.name == partner.name;
      });

      if( indexOfPartner >= 0 ) {
         merge( values, indexOfPartner, value );
      }
      else {
         values.push( value );
      }
   }

   function merge( list, index, value ) {
      // do whatever merge means here
      // for example:
      _.extend( list[index], value );
   }

   var FB = new Firebase(YOUR_URL);
   var values = [];

   FB.child('TYPEA').on('child_added', function(snapshot) {
      addWithPartner( snapshot.val(), snapshot.name(), 'typeA' );
   });

   FB.child('TYPEB').on('child_added', function(snapshot) {
      addWithPartner( snapshot.val(), snapshot.name(), 'typeB' );
   });

</script>