【问题标题】:javascript function inside jquery foreach loop doesn't wait for responsejquery foreach循环中的javascript函数不等待响应
【发布时间】:2015-04-19 03:22:03
【问题描述】:

我的 foreach 循环:

jQuery(".custom-checkbox").each(function() {
      if (jQuery(this).attr('data-action') == 'true') {

      if(deleteQuoteItemFromListing(jQuery(this).attr('data-id'))){
                    console.log('passed');
            }else{
                    console.log('failed');
            }
      }    
 });

而且功能是(它使用原型)但它成功

function deleteQuoteItemFromListing(id){
    //does someoperations and on success
    delurl = getDelUrl()+id; //baseurl/module/action/delete/id
    new Ajax.Request(delurl,{
        method: 'get',
        onSuccess: function(transport){
            return TRUE;
        } 
    })
}

但问题是所有 foreach 立即执行,并且不等待函数的响应。即使操作成功,它也会打印failed。

更新

我首先尝试的另一种方式是这样

jQuery('.delete-from-quote').click(function() {
        var i = 0, j = 0;
        jQuery(".custom-checkbox").each(function() {
            if (jQuery(this).attr('data-action') == 'true') {
                i++;
            }
        });


        if (i == 0) {
            alert('please choose product');
            return false;
        }

        jQuery(".custom-checkbox").each(function() {

            if (jQuery(this).attr('data-action') == 'true') {

                var urlData = "<?php echo $this->getUrl('qquoteadv/index/delete/'); ?>";
                urlData += "id/" + jQuery(this).attr('data-id') + "/"

                var ajax = jQuery.ajax({
                    type: "GET",
                    url: urlData,
                    success: function(msg) {
                        j++;
                    }
                })

            }
          if(i==j){location.reload();} //after completing all, reload the page
        });
  });

问题是要知道所有操作已完成并重新加载页面。

【问题讨论】:

    标签: javascript jquery asynchronous foreach


    【解决方案1】:

    我的猜测是您省略的代码正在执行异步 ajax 调用。由于默认情况下 ajax 是异步的,因此您在此处编写的代码($.ajax 或其他)启动该进程,但随后该进程在后台继续,而您的代码继续运行。

    没有合理的方法让deleteQuoteItemFromListing 函数等待 响应。 (虽然可以执行 同步 ajax,A)它会通过锁定浏览器 UI 导致糟糕的用户体验,并且 B)jQuery 将在某个阶段删除该选项,迫使您直接使用如果您想继续这样做,请转到 XHR。)

    相反,通过让您的函数返回承诺或接受回调,然后解决承诺或在完成后调用回调,重构您的代码以接受 Web 编程的异步特性。

    以下是 Promise 版本的大致概念:

    jQuery(".custom-checkbox").each(function() {
        if (jQuery(this).attr('data-action') == 'true') {
            deleteQuoteItemFromListing(jQuery(this).attr('data-id'))
                .done(function(id) {
                    console.log(id + ' passed');
                })
                .fail(function(id) {
                    console.log(id + ' failed');
                });
        }    
    });
    
    function deleteQuoteItemFromListing(id){
        var d = jQuery.Deferred();
        jQuery.ajax(/*...*/)
            .done(function() {      // This bit assumes the deletion worked if
                d.resolveWith(id);  // the ajax call worked, and failed if the
            })                      // ajax call failed; if instead the ajax
            .fail(function() {      // call always works and returns a flag,
                d.rejectWith(id);   // adjust accordingly
            });
        return d.promise();
    }
    

    【讨论】:

    • 是的,函数调用了 ajax。
    • @K.C.:您需要更新问题以表明这一点,但我实际上猜对了,所以这个答案解决了这个问题。
    【解决方案2】:

    使用回调确保函数被执行。

    jQuery(".custom-checkbox").each(function () {
        if (jQuery(this).attr('data-action') == 'true') {
            deleteQuoteItemFromListing(jQuery(this).attr('data-id'), handleData);
    
        }
    });
    
        function handleData(data) {
        if (data) {
            console.log('passed');
        } else {
            console.log('failed');
        }
    }
    
    
    function deleteQuoteItemFromListing(id, callback) {
        //does someoperations and on success
        delurl = getDelUrl() + id; //baseurl/module/action/delete/id
        new Ajax.Request(delurl, {
            method: 'get',
            onSuccess: function (transport) {
                callback(true);
            }
        })
    }
    

    我希望这对你有用。你需要在另一个函数之外定义handleData函数。

    【讨论】:

    • 回调函数没有触发
    • @K.C.我给了你一个想法,它不一定会运行,你可以进一步调试你的代码。 ;)
    【解决方案3】:

    何时使用 jquery。

    您需要将这些 Deferred 排入 Deferred 数组中,然后一次应用所有函数。

    如果一个失败就失败,如果所有成功都会通过。

    看看jQuery When

          var queue = [];
          var items = 0;
          return new $.Deferred(function (deferred) {
          $(".custom-checkbox").each(function () {
           if ($(this).attr('data-action') == 'true') {
            items++;
            queue.push(function () {
                new Ajax.Request(delurl, {
                    method: 'get',
                    onSuccess: function (transport) {
                        items--;
                        if(items === 0)
                            deferred.resolve();
                    },
                    onError:function(e){
                      deferred.reject(e);   
                    }
                });
            });
        }
    });
    
    //now resolve all of the deferred fns
    
      $.when(queue).done(function(){
          console.log('All went well');
      })
     .fail(function(e){
          console.log('Error ' + e);
      });
    });      
    

    【讨论】:

      【解决方案4】:

      (部分)你的问题在于这个简单的陈述:

      return TRUE;
      

      在 JavaScript 中,“true”布尔值是小写的:

      return true;
      

      解释器认为TRUE 是一个变量,并将抛出一个ReferenceError,因为它没有在任何地方设置/定义,这意味着函数永远不会返回true。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-09
        • 1970-01-01
        • 1970-01-01
        • 2017-07-21
        • 2021-09-03
        相关资源
        最近更新 更多