【问题标题】:Do while javascript issue做while javascript问题
【发布时间】:2011-10-20 12:58:02
【问题描述】:

我正在尝试在一个 do while 循环中发送多个帖子,但未添加结果

<script type="text/javascript">
function action() {
    var initval = 1;
    var endval = 5;
    do {
    var action_string = 'txtuser=someone';

    $.ajax({
                    type: "POST",
                    url: "http://localhost/js.php",
                    data: action_string,
                    success: function(result){
                       $('div#append_result').append(initval + ',<br/>');
                     }  
                });
    initval++;
     } while (initval <= endval);
  }
</script>

输出是: 5、 5、 5、 5、 5、

我需要输出为: 1、 2、 3、 4、 5、

【问题讨论】:

    标签: javascript ajax while-loop do-while


    【解决方案1】:

    由于 AJAX 的异步特性,当您的成功函数针对任何生成的 AJAX 请求运行时,循环已完成并且initval 设置为 5。您需要在以下位置捕获initval 的状态每个请求的开始并在success() 方法中使用捕获的状态。关闭值是最简单的方法:

    function action() {
        var initval = 1;
        var endval = 5;
        do {
            var action_string = 'txtuser=someone';
    
            ( function( captured_initval ){
                $.ajax({
                    type: "POST",
                    url: "http://localhost/js.php",
                    data: action_string,
                    success: function(result){
                        $('div#append_result').append(captured_initval + ',<br/>');
                    }  
                });
            }( initval ) );
    
            initval++;
        } while (initval <= endval);
    }
    

    但请理解,一个或多个请求可能会在服务器上挂起,从而允许后一个请求先完成,这可能会导致 1, 2, 5, 3, 4 或类似的东西。

    此外,使用元素的 ID 比在哈希选择器前面加上元素标签名称要快得多。另外,您应该避免每次成功运行时重新查询 DOM 以获取结果 DIV。抓住一次,在需要时使用:

    function action() {
        var initval = 1;
        var endval = 5;
        do {
            var action_string = 'txtuser=someone',
                $AppendResult = $('#append_result');
    
            ( function( captured_initval ){
                $.ajax({
                    type: "POST",
                    url: "http://localhost/js.php",
                    data: action_string,
                    success: function(result){
                        $AppendResult.append(captured_initval + ',<br/>');
                    }  
                });
            }( initval ) );
    
            initval++;
        } while (initval <= endval);
    }
    

    【讨论】:

    • 您不是在“关闭”interval 的值,而是在避免关闭的影响(仍然存在)。
    • 确实,我正在避免原始关闭的影响。但是我不是通过创建一个带有我喜欢效果的闭包的新范围来这样做吗?请记住,成功回调驻留在我创建的立即调用的函数表达式中,导致“捕获”值被关闭...
    • 非常非常感谢,大家都很有帮助!!
    • +1 表示第一块代码(和点)。我要争论的第二点:$('div#append_result'); 中的 div 会减慢速度,需要删除“div”部分而不是缓存结果并在成功回调中使用它。 $("#append_result")document.getElementById("append_result") 慢得可以忽略不计,所以我认为在这个特定的解决方案中不需要任何缓存。
    • @karim79 感谢您的 +1。我同意应该删除选择器的 div 部分。但是,缓存document.getElementById() 的结果肯定比调用它 5 次以上更有效,不是吗?所以 jQuery 版本似乎也是如此。
    【解决方案2】:

    这是因为 ajax 的异步行为: 这是修改后的版本:

    var initval = 1;
    var endval = 5;
    function action(){
        var action_string = 'txtuser=someone';
        $.ajax({
            type: "POST",
            url: "http://localhost/js.php",
            data: action_string,
            success: function(result){
               $('div#append_result').append(initval + ',<br/>');
               initval++;
               if(initval<=endval)
                action();
            }  
        });
     }
    

    现在这在某种程度上是一种顺序方法。 注意:我假设每个ajax请求都返回成功,如果有错误,你应该在错误回调中处理它们。

    【讨论】:

      【解决方案3】:

      Ajax 请求是异步的,这意味着在成功处理程序返回时,循环已经完成。相反,您可以创建一个闭包来保留该值:

      success: (function(i){
          return function() {
               $('div#append_result').append(i + ',<br/>');
          }
      })(initval)
      

      【讨论】:

      • 这不是闭包,它是在避免闭包的影响。匿名函数仍然有一个对 initval 的闭包。
      • @RobG - 正如我在回复对我自己的回答的评论时所说的,我非常不同意。
      • @JAAulde - 实际上我们同意。然而,额外的闭包是一个副作用,而不是原来的闭包被破坏的原因。换句话说,它现在工作的事实不是因为额外的闭包,而是因为将值传递给另一个函数(并且只是因为该值是原始值)。
      猜你喜欢
      • 2013-12-10
      • 1970-01-01
      • 2020-07-07
      • 2015-01-04
      • 2021-11-18
      • 1970-01-01
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多