如何停止循环执行,直到for循环内的DWR方法执行完成

时间:2013-07-15 21:24:14

标签: javascript dwr

请参阅此代码:

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()的执行,然后才能进行下一次迭代。

提前致谢。

3 个答案:

答案 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设为全局变量,并且我稍微更改了您的代码。