同步代码

时间:2011-12-21 14:04:31

标签: javascript jquery

我使用getPropertyId函数进行ajax调用以获取数据。我使用回调来获得结果然后我使用它们。我的问题是第二个循环在第一个循环结束之前启动,即使我把它放在函数内部。我可以同步我的代码以在第一个循环结束后启动第二个循环吗? 感谢

Plugins.DataHelper.getPropertyId(PropertyID, function(data){
    //code using data retrived with getPropertyId function

    $.each(list, function(index,value){
    //code "A" containing asynchronous calls
    });
});

$.each(filtredList, function(index,value){
    //code "B"
});

5 个答案:

答案 0 :(得分:1)

你真的可以创建一个同步(=阻塞)请求,但这是非常糟糕的浏览器行为。更好的方法是让回调函数适合你,所以当第一个ajax调用完成时(成功/错误)你需要“继续”代码。

Plugins.DataHelper.getPropertyId(PropertyID, function(data){
    XHRobject.onreadystatechange = function() {
        if( XHRobject.readyState === 4 ) {
            $.each(list, function(index,value){
               //code "A"
            });
        }
    }
});

注意,这是一个简化的例子来说明原理。既然你也标记了jQuery,你可以通过调用promise对象使这个非常georgous。看起来像

Plugins.DataHelper.getPropertyId(PropertyID, function(data){
    $.ajax({}).done(function() {
        $.each(list, function(index,value){
           //code "A"
        });
    });
});

答案 1 :(得分:1)

这是JavaScript的本质 - 你绝对应该习惯基于事件的编程,以避免将来出现类似的问题。

基本上这样的事情应该有效:

Plugins.DataHelper.getPropertyId(PropertyID, function(data){
    //code using data retrived with getPropertyId function

    $.each(list, function(index,value){
        //code "A"
    });
    $.each(filtredList, function(index,value){
        //code "B"
    });
});

除非你在“代码A”中进行AJAX调用。在这种情况下,你运气不好,应该改变你的“代码A”来使用同步调用(通常是个坏主意)或者根据事件重写你的代码。

一个想法是确定要处理的元素数量,然后在处理完每个项目后调用回调。此回调应检查是否已处理所有项目(通过递增计数器并将其与要处理的项目数量进行比较 - 此机制类似于锁定的工作方式)。当函数确定所有项目都已处理完毕后,它会执行一些操作(否则不会)。

答案 2 :(得分:1)

您应该可以通过在回调函数中移动第二个'each'调用来实现此目的:

Plugins.DataHelper.getPropertyId(PropertyID, function(data){
  //code using data retrived with getPropertyId function

  $.each(list, function(index,value){
    //code "A"
  });

  $.each(filtredList, function(index,value){
    //code "B"
  });
});

修改:有关详细信息,请查看此文章:flow control in javascript

答案 3 :(得分:0)

第一个等待,直到ajax-call完成。

与此同时,脚本会继续运行,并且每次首先执行第二步。

尝试在第一个每个循环之后放置第二个。

答案 4 :(得分:0)

您可以使用传统的Lock语义

Plugins.DataHelper.lock = false;//release
Plugins.DataHelper.getPropertyId(PropertyID, function(data){
    //code using data retrived with getPropertyId function

    $.each(list, function(index,value){
      Plugins.DataHelper.lock = true;//acquire
      //code "A"
      Plugins.DataHelper.lock = false;//release
    });
});
while(Plugins.DataHelper.lock)
   continue;//wait until released
$.each(filtredList, function(index,value){
    //code "B"
});

或者你可以在完成ajax xhr的回调后附加下一个函数来调用。

var nextF = function(){};
Plugins.DataHelper.getPropertyId(PropertyID, function(data){
    //code using data retrived with getPropertyId function

    $.each(list, function(index,value){
      //code "A"
      nextF();
    });
});
nextF = function(){
$.each(filtredList, function(index,value){
    //code "B"
});
}//You need to pass the scope to the nextF function like nextF.call(scope) where scope is cached somewhere