请参阅此代码:
for(var k=0;k<pods.length;k++){
var currentQueryList = new Array();
currentQueryList[0]=pods[k].queryname;
console.log("Hello :"+i);
queryBuilderDWRService.getDataForAllPods(currentQueryList, {callback:function(map){
podsDataMap = map;
console.log("Hello"+k+":");
var pod = pods[k];
displayPod(k, pod, false);
}});
}
在此代码中,for循环在调用queryBuilderDWRService.getDataForAllPods()
之前完成,返回实际数据,我用它来从数据库中获取数据。
我尝试console.log("Hello"+i);
它打印Hello :1, Hello :2, Hello :3, Helllo :4,
直到数组长度而没有来自DB的数据,这意味着for循环在queryBuilderDWRService.getDataForAllPods()
返回之前完成执行。
我需要的是,一旦控件进入for循环,就必须完成queryBuilderDWRService.getDataForAllPods()的执行,然后才能进行下一次迭代。
提前致谢。
答案 0 :(得分:5)
您可以使用“异步伪递归”而不是for
循环,我使用的一般模式是:
var pods = [ ... ];
(function loop() {
if (pods.length) {
var pod = pods.shift(); // take (and remove) first element
// do something with "pod"
...
// recurse - put this inside a finish callback if "do something" is async
loop();
}
})(); // closing braces start invocation immediately
在你的情况下,对loop
的调用应该是你回调函数中的最后一件事。
注意:通过将loop()
的调用替换为setTimeout(loop, 0)
,此模式还可用于避免因长时间运行的非异步操作而出现“浏览器无响应”错误。
setTimeout
的这种使用将同步递归函数转换为异步伪递归函数,在此过程中避免了任何堆栈溢出错误的可能性。
唯一的缺点是迭代之间的最小延迟为4ms。
答案 1 :(得分:0)
从您设置的方式来看,您正在进行的调用可能是异步的,因此循环将在回调到您定义的函数之前完成执行。因此,您似乎想要构建currentQueryList数组,然后对getDataForAllPods进行一次调用,然后在回调中完成显示。地图中返回的是什么?
答案 2 :(得分:0)
你应该使用一个自动执行的函数,称为闭包。
var currentQueryList = [];
for(var i=0,l=pods.length; i<l; i++){
(function(i){
currentQueryList[0]=pods[i].queryname;
console.log('Hello :'+i);
queryBuilderDWRService.getDataForAllPods(currentQueryList, {callback:function(map){
podsDataMap = map;
console.log('Hello'+i+':');
var pod = pods[i];
displayPod(i, pod, false);
}});
})(i);
}
问题是,当你调用事件时,循环已经运行了。由于i
在您的循环中作用域,因此当事件触发时,它会查找i
的值pods.length-1
,因为您已使用<
。您需要将增量的范围存储到单独的存储空间中,这些存储空间将在事件触发时被访问。
请注意,您已将podsDataMap设为全局变量,并且我稍微更改了您的代码。