Meteor递归方法调用导致死循环
Meteor recursive method call causes infinite loop
给定树中的一个 (parent) 节点,我需要检索 parent 下 children 加上 parent 下的 [1] 个 children children加上parent的children的children等等[2]来自[1]的children的数量[=25] =].
我的测试数据有一个parent有两个children。我的方法-
Meteor.methods({
...
'getSubCounts': function(selectedNodeId){
var children = ItemList.find({"parent.parentid": selectedNodeId}).fetch();
var numChildren = children.length;
console.log("Number of children of " + selectedNodeId + ": " + numChildren);
var openChildrenCount = children.filter(function(row) {
return (row.status === "OPEN");
}).length;
for (i = 0; i < numChildren; i++) {
console.log("iterations for child " + i + ": " + children[i]._id);
Meteor.call('getSubCounts', children[i]._id, function(error, result) {
if(error) {
console.log("error occured during iteration " + error);
} else {
numChildren = numChildren + result.numChildren;
openChildrenCount = openChildrenCount + result.openChildrenCount;
}
});
}
return {numChildren: numChildren, openChildrenCount: openChildrenCount};
},
...
});
我在 client-side 助手中调用 -
'subcounts': function(){
if (this._id != null) {
Meteor.call('getSubCounts', this._id, function(error, result) {
if(error) {
// nothing
} else {
Session.set('subcountsdata', result)
}
});
从(浏览器)输出来看,第一个 child 似乎按预期迭代,但第二个陷入无限循环。 (注意parent节点id是8veHSdhXKjyFqYZtx
,children id是iNXvZGaTK3RR6Pekj,C6WGaahHrPiWP7zGe
)
Number of children of 8veHSdhXKjyFqYZtx: 2
iterations for child 0: iNXvZGaTK3RR6Pekj
Number of children of iNXvZGaTK3RR6Pekj: 0
iterations for child 1: C6WGaahHrPiWP7zGe
Number of children of C6WGaahHrPiWP7zGe: 0
iterations for child 1: C6WGaahHrPiWP7zGe
Number of children of C6WGaahHrPiWP7zGe: 0
iterations for child 1: C6WGaahHrPiWP7zGe
Number of children of C6WGaahHrPiWP7zGe: 0
iterations for child 1: C6WGaahHrPiWP7zGe
Number of children of C6WGaahHrPiWP7zGe: 0
....
为什么在这种情况下第二次迭代会无限发生?这看起来是由于反应性,但我不太明白真正的原因。
很可能您只是在方法函数中缺少一个 var i
。
在不将 i
声明为局部变量的情况下,您使用全局范围变量,每次调用您的方法时都会将其重新分配为 0。
顺便说一句:
- 避免递归 Meteor 方法。您正在创建一个网络请求循环。如果您需要递归,请在专用函数中进行外部化。
- 避免在助手中调用 Meteor 方法。请改用
ReactiveVar
并仅在必要时进行调用,通常是在 Blaze 模板生命周期挂钩(如 onCreated)或事件侦听器中。
给定树中的一个 (parent) 节点,我需要检索 parent 下 children 加上 parent 下的 [1] 个 children children加上parent的children的children等等[2]来自[1]的children的数量[=25] =].
我的测试数据有一个parent有两个children。我的方法-
Meteor.methods({
...
'getSubCounts': function(selectedNodeId){
var children = ItemList.find({"parent.parentid": selectedNodeId}).fetch();
var numChildren = children.length;
console.log("Number of children of " + selectedNodeId + ": " + numChildren);
var openChildrenCount = children.filter(function(row) {
return (row.status === "OPEN");
}).length;
for (i = 0; i < numChildren; i++) {
console.log("iterations for child " + i + ": " + children[i]._id);
Meteor.call('getSubCounts', children[i]._id, function(error, result) {
if(error) {
console.log("error occured during iteration " + error);
} else {
numChildren = numChildren + result.numChildren;
openChildrenCount = openChildrenCount + result.openChildrenCount;
}
});
}
return {numChildren: numChildren, openChildrenCount: openChildrenCount};
},
...
});
我在 client-side 助手中调用 -
'subcounts': function(){
if (this._id != null) {
Meteor.call('getSubCounts', this._id, function(error, result) {
if(error) {
// nothing
} else {
Session.set('subcountsdata', result)
}
});
从(浏览器)输出来看,第一个 child 似乎按预期迭代,但第二个陷入无限循环。 (注意parent节点id是8veHSdhXKjyFqYZtx
,children id是iNXvZGaTK3RR6Pekj,C6WGaahHrPiWP7zGe
)
Number of children of 8veHSdhXKjyFqYZtx: 2
iterations for child 0: iNXvZGaTK3RR6Pekj
Number of children of iNXvZGaTK3RR6Pekj: 0
iterations for child 1: C6WGaahHrPiWP7zGe
Number of children of C6WGaahHrPiWP7zGe: 0
iterations for child 1: C6WGaahHrPiWP7zGe
Number of children of C6WGaahHrPiWP7zGe: 0
iterations for child 1: C6WGaahHrPiWP7zGe
Number of children of C6WGaahHrPiWP7zGe: 0
iterations for child 1: C6WGaahHrPiWP7zGe
Number of children of C6WGaahHrPiWP7zGe: 0
....
为什么在这种情况下第二次迭代会无限发生?这看起来是由于反应性,但我不太明白真正的原因。
很可能您只是在方法函数中缺少一个 var i
。
在不将 i
声明为局部变量的情况下,您使用全局范围变量,每次调用您的方法时都会将其重新分配为 0。
顺便说一句:
- 避免递归 Meteor 方法。您正在创建一个网络请求循环。如果您需要递归,请在专用函数中进行外部化。
- 避免在助手中调用 Meteor 方法。请改用
ReactiveVar
并仅在必要时进行调用,通常是在 Blaze 模板生命周期挂钩(如 onCreated)或事件侦听器中。