2013-07-15 45 views
2

请参阅此代码中:如何停止循环执行,直到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,直到数组长度没有数据从数据库,这意味着for循环完成其执行之前比queryBuilderDWRService.getDataForAllPods()返回。

我需要的是,一旦控制进入for循环,它必须完成queryBuilderDWRService.getDataForAllPods()的执行,然后才能进行下一次迭代。

在此先感谢。

+0

答案取决于如何编写QueryBuilderDWRService。由于getDataForAllPods异步执行,所以它可能有一个信号通过回调,事件触发等完成的方式。 – Egg

+0

@Egg我希望这将是OP代码中的回调函数... – Alnitak

回答

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应该是里面的最后一件事你的回调函数。


NB:该模式还可以用于避免“浏览器没有响应”通过用setTimeout(loop, 0)替换调用loop()较长运行非异步操作看到错误。

这种使用setTimeout将同步递归函数转换为异步伪递归函数,避免了任何堆栈溢出错误的可能性。

唯一的缺点是迭代之间的4ms最小延迟。

+0

感谢您回复Alnitak。 。对不起,我无法根据你所说的去做代码改变..你可否请加我全码 –

+0

不,这不会教你任何东西。你需要把'var currentQueryList = [pod.queryname];在'shift'行之后,并将'loop()'放在回调的最后一行。您将不再拥有变量'k',因此只需在'loop'之外创建它并在每次迭代中增加它。 – Alnitak

+0

非常感谢Alnitak ..您的代码完全符合我的要求.. –

0

从你设置的方式来看,你所做的调用可能是异步的,因此在回调你定义的函数之前,循环会完成执行。所以看起来你想构建你的currentQueryList数组,然后对getDataForAllPods进行一次调用,然后在回调中完成显示。这是什么在地图中返回?

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

+0

这将修复变量绑定问题,但每个查询仍然会并行运行而不是串联运行。 – Alnitak