强制JavaScript以所需顺序执行

时间:2012-01-10 13:50:40

标签: php javascript jquery mysql

我试图让Javascript以我想要的顺序执行函数时遇到问题。我正在尝试获取一个jQuery模式表单来加载基于特定选择的信息。我有两个需要加载的SELECT框,但第二个SELECT框的内容完全取决于第一个SELECT框的选定值。

我做了以下功能来请求我需要的信息:

function get_Subjects(varID, callback){
    $.post("../vars/get_SID.php", { vid : varID },  
        function(result){
            getInfo('tbsubjectdiv', '../vars/findSubjectlist.php?sid='+result);
        });
    callback();
}

function get_Selectedfields(varID, callback){
    $.post("../vars/requestTblock.php", { vid : varID },  
        function(result){
            populateForm('tbWiz', result);
            document.form_tbWiz.varname.disabled = true;
            $('.trSearch').hide();
            $('.trValueset').hide();
        });
    callback();
}

function get_TextblockType(varID, callback){
    $.post("../vars/requestVtype.php", { vid : varID },  
        function(result){
            if(result == 0){ //Opzoeken
                $('.trSearch').show();
            }else if(result == 1){ //Datum vergelijken
                $('.trSearch').show();
                $('.trValueset').show();
            }else if(result == 2){ //Percentage
                //
            }
        });
    callback();
}
  1. 第一个函数检查MySQL数据库中的所选值 FIRST SELECT字段,并将结果加载到第二个字段中 SELECT字段。

  2. 第二个函数请求其余的表单数据,并使用populateForm()填充表单。它也隐藏起来 我的表格中的某些部分正在准备第三部分。

  3. 第三个函数基本上要求显示表单的哪些部分,因为它并不总是相同。

  4. 这背后的整个想法是我想使用populateForm()来填充所有表单字段。为了使populateForm()能够正确设置所选的SELECT选项,特定的SELECT字段必须首先包含它需要选择的OPTION。说得通。我尝试用我的第一个函数来确保这一点,它将加载所有的OPTION。然后我尝试使用get_Selectedfields()来填充所有正确的值。这不是发生的事情。无论我尝试做什么,第一个函数中的getInfo()总是被称为LAST。这使得populateForm()无法选择合适的选项,这让我很生气。

    我试图通过这样做来“强制”执行顺序:

    function getTextblock(var_ID){
    get_Subjects(var_ID, function() {
        get_Selectedfields(var_ID, function() {
            get_Textblocktype(var_ID, function() {
                // Done
            });
        });
    }); 
    

    }

    当我意识到它仍然没有按照我想要的方式工作时,我决定使用Chrome的开发者工具来检查所有内容的执行顺序。这一切都按预期工作,但在最后它直接跳回到getInfo(),这是我调用的FIRST函数的一部分。我绝对不知道为什么getInfo()最后被执行。如果这只是在一开始就执行,我希望它在那里执行,那么一切正常。

5 个答案:

答案 0 :(得分:3)

你必须在post请求的回调函数中调用回调:

function get_Subjects(varID, callback){
    $.post("../vars/get_SID.php", { vid : varID },  
        function(result){
            getInfo('tbsubjectdiv', '../vars/findSubjectlist.php?sid='+result);      
            callback();
        });

}

function get_Selectedfields(varID, callback){
    $.post("../vars/requestTblock.php", { vid : varID },  
        function(result){
            populateForm('tbWiz', result);
            document.form_tbWiz.varname.disabled = true;
            $('.trSearch').hide();
            $('.trValueset').hide();
            callback();
        });

}

function get_TextblockType(varID, callback){
    $.post("../vars/requestVtype.php", { vid : varID },  
        function(result){
            if(result == 0){ //Opzoeken
                $('.trSearch').show();
            }else if(result == 1){ //Datum vergelijken
                $('.trSearch').show();
                $('.trValueset').show();
            }else if(result == 2){ //Percentage
                //
            }
            callback();
        });

}

答案 1 :(得分:1)

POST正在您的函数中异步处理,因此您的“回调”实际上只是在初始调用后几乎立即执行,而$.post的回调正在发布后执行。这有助于你解决问题吗?您可能需要在$.post("../vars/get_SID.php", { vid : varID }...

的回调中启动剩余的流程

$.post$.ajax的简写,因此您可以read up a bit more in the jQuery docs,但我不建议切换到同步请求。如果你必须在下一个请求完成之前完成一个请求,那么从回调开始下一步就是要走的路。

答案 2 :(得分:1)

你正在使用ajax。第一个是异步的。如果从函数(结果)块调用函数,则它们将按顺序发生。

或者(这不是一个好主意,但你可以这样做)使用$ .ajax()对象并将async设置为false。

答案 3 :(得分:1)

由于您不知道ajax请求实际需要多长时间,因此您只能在ajax响应中链接事件:

function getTextblock(var_ID){
    $.post(YOUR_TARGET, YOUR_DATA, function(result){
        YOUR_CODE
        // CHAIN HERE, call new function or sub ajax request
    });
}

答案 4 :(得分:1)

韦斯利,

javascript将始终按预定义顺序执行。如果你在代码中间添加了一堆“alerts()”,你可以尝试一下。

回调并非如此,因为它们将被移动到javascript上执行堆栈的底部,我们无法确定顺序,因为它们是由AJAX返回的,它由定义是异步的。

即使您的ajax以毫秒为单位执行,在脚本块中的所有方法都完成之前,回调也不会执行。

你有三个选择:

  1. 链接回调中的所有方法序列。请不要回拨!! 它应该是你,但是那个会调用它们的“系统”。
  2.   // The data you need first
      function myStartPoint() {
        $.post(url, function(result) {
           // do what you need with this result (this is your callback, but anonymous)
           // then, call the next step
           secondPoint();
        });
      }
    
      function secondPoint() {
        $.post(url, function(result) {
          // again, the callback is anonymous... your hardly need to declare something named callback
          // chain how many points as you need
          nextPoint();
        }
      }
    
    1. “强制”ajax与 async:false 选项同步。这可能会导致性能问题。
    2. 最丑的是使用该死的 setTimeout ,这是非常非常错误的,但是在你的情况下可以工作,因为,setTimeout将把方法放在执行堆栈的底部,即使这些回调预计会很快。说真的,我只是提出这个选项,因为最终有人会说出来......不要走这条路。