如何处理在javascript中访问数据结构的两个回调
How do I deal with two callbacks accessing a datastructure in javascript?
更新 2: 我认为这是一个更好的解释:
我有两个回调,每个回调都在填满一个数组。我想以某种方式合并这些数组。这样做的天真方法是等到数组被填满,然后与 for 循环合并。我不能这样做,因为没有真正的方法来检查回调是否"完成"。
下一步可能是这样的:每次通过回调下载对象时,它都会检查合并数组(称为混合),并查看它是否包含"伙伴"对象。如果是:则合并到该合作伙伴对象中。如果没有,则插入该对象。
我担心竞争条件:回调 1 看到数组为空,决定插入其中,但随后控制切换到首先插入的回调 2。回调 1 现在应该合并而不是插入,但当控件切换回来时,它会插入。
如果我可以制作一个原子"检查和插入/合并"代码块,可能会有所帮助。有没有办法做到这一点?
更新 1:现在有了代码,还有更多的单词!
谢谢大家的回复。我去尝试尽可能简化代码。
的话:
我有一个名为 mixed 的数组。混合应以:所有类型(A)的对象结束,如果它们具有类型(B)的类似对象(也称为"私有"),则应合并它们。
这意味着使用两个使用回调的函数 - getAllA 和 getAllB。现在,我调用两者,手动等待一会儿,然后运行一个执行合并的 for 循环。
我需要做的是编辑我的代码,以便在回调中进行合并。但是,我想不出一种不创建竞争条件的方式进行合并的方法。
天真地,我可能想先用 A 类型的对象填充混合,然后遍历 B 对象并根据需要合并它们。但是,我不能这样做,因为无法查看您是否在 firebase 中使用了 on("contact_added")。我认为我想要的是一个并发数组结构,但我不知道如何使用内置的数组结构。我担心自己做,因为我不知道如何检查我是否做错了。比赛条件就是这样棘手。
现在,代码:以下是您需要参考的脚本:
以下是我粘贴到 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);
}
};
我想做的是将逻辑从 for 循环移动到回调中,因为如果您立即运行 for 循环,数组将不会通过回调完成下载。
旧条目:
我有两个回调访问Firebase上的数据列表。
回调 1 获取类型 A 的对象。回调 2 获取 B 类型的对象。
我的目标 - 有一个正确合并 A 和 B 类型的对象的数组。
大多数(但必须全部)类型 B 的对象都有一个类型 A 的"伙伴"对象。一些类型 A 的对象具有类型 B 的伙伴对象。
对于从 Firebase 提取的每个对象,我想看看它们的伙伴是否在数组中。如果没有,则插入。如果是这样,则改为与合作伙伴"合并"。
如果没有并发数据结构,我想不出一种方法来做到这一点 - 但我不知道如何在 Javascript 中做到这一点。
我怎样才能创建该并发阵列,或者找到一种以其他方式实现我的目标的方法?
<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>
JS的值为零,对吧? 无论如何,如果他们不这样做,这个答案是没有用的。
我要做的是在主数组上有一个函数,你传递一个对象,并检查它的伙伴是否在数组中。 如果是,则返回所述对象,否则返回 nil。 这样,如果需要,您已经有了要执行合并的对象。
此外,我不确定您的措辞,但您似乎担心并发性成为一个问题(竞争条件、覆盖等)? 如果是这种情况,这是使用互斥锁的完美示例(如果 js 还没有它们,您可以非常轻松地制作自己的)。只需将我上面提到的功能在开头锁定并在结束时解锁,您就可以避免读取过时的数据。 希望有帮助。
不是100%确定我理解问题的细节,但知道javascript是单线程的可能会有所帮助,因此您永远不必担心真正的并发性。 您的回调将始终一次发生一次。
因此,您不需要"并发数据结构"。 很可能任何数据结构都可以工作,因为javascript中没有并发性。:-)
就像前面的回答中所解释的,javascript 在限制在主窗口时是单线程的;即使一个函数被异步调用,它的执行也将是"原子的"(不会中断)。因此,您不能有竞争条件。
但是,处理问题"我不能这样做,因为没有真正的方法来检查回调是否"完成",尝试提供等待/通知(All)机制 http://www.megiddo.ch/jcon-q-rency。我用它来做和你一样的操作。
有了它,您可以延迟函数的执行,直到满足某个条件。那是你的"//////等待"。当getAllA()和getAllB()完成后,它们可以通知负责执行for(b在privates中){..}循环的等待函数。
- 将json回调数据转换为日期
- 如何降低此函数的复杂性,该函数根据数据类型进行回调
- 从AJAX回调函数中分离数据
- 行上的Primefaces数据表选择javascript回调
- 访问通过XHR.onreadystatechange回调中的XHR.send(data)发送的数据
- Angular 2中Observable中获取数据后的队列/回调函数
- Highcharts xAxis将格式化程序回调数据标记为空
- DimpleJS-在getTooltipText回调中获取原始数据
- Node.js,为事件分配回调函数'数据'
- 使用回调获取图像像素数据
- 试图从嵌套的回调函数返回数据
- 科尔多瓦 PhoneGap Android 回调与数据
- 将数据注入异步回调(使用 node.js)
- 如何处理在javascript中访问数据结构的两个回调
- 了解函数(错误、数据)回调
- angularfire,对检索到的数据进行回调
- 将数据从回调传递到 React 组件
- 闪亮的数据表回调
- 是否保证传递给 always 函数的回调将在函数(数据)回调完成其工作后调用
- 有AngularJS数据更新回调吗?如何在数据更改时手动更新页面