jQuery多个AJAX同步请​​求&动态添加html和事件

时间:2017-11-23 20:25:22

标签: javascript jquery ajax synchronous

我有以下javascript

// JavaScript Document
$("[name=students]").each(function(){

        var student_id  = $(this).attr("data-student_id");

        ///////////////////////////////////////////////////////////////////
        ajax_call = $.ajax({
            method: "POST",
            url: "/load.php",
            dataType: "html",
            async: true,
            beforeSend: function(){
            },
            data:   { 
                        student_id: student_id
                    },

            success: function( response ) 
            {   
                // dynamically add radio buttons
                // html response is radio buttons with NAME of as_xxxx inside of parent div[name=students] element already in the DOM
                $("[name=students][data-student_id='"+student_id+"']").fadeIn( "slow").html(response).show();

            },
            error: function(xhr, textStatus, errorThrown)
            {
                // show error message
            },
        });
        //END AJAX/////////////////////////////////////////////////////////////////
    }).promise().done( function(){ 

        save_data();
    });
});
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  SAVE
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function save_data()
{

    //$(document).on('click','[name=student][name^=as_]',function(event) // WORKS IF ajax ASYNC = TRUE

    $("[name=student][name^=as_]").on("click",function(event)  // DOES NOT WORK IF ajax ASYNC = TRUE.   Works if ASYNC = FALSE
    {
        // SAVE RADIO BUTTON DATA ON CLICK
    });
}
</javascript>

如果异步为FALSE,代码工作正常。但如果asnyc为TRUE,那么我就无法点击任何动态添加的单选按钮。

我假设promise()。done代码在所有ajax同步请求完成之前触发。

有没有办法确保完成同步ajax请求的循环?或者为什么代码不起作用?

2 个答案:

答案 0 :(得分:1)

因此,要制作多个具有异步性质的ajax请求,因为我们处理的是http个请求,您应该考虑在Promise.all api中包含一些逻辑的promiseAll 。 此示例显示如何进行多个异步http调用并收集结果,因此您有类似

的内容
promiseAll(items, callback)
  .then((results) => {
    console.log(results)
  })
  .catch((error) => {
    console.log(error)
  });

您将从then获取http调用的所有结果,而callback实际上会执行异步作业(实际上可能是每种异步过程)。

// Simple XMLHttpRequest
// based on https://davidwalsh.name/xmlhttprequest
SimpleRequest = {
  call: function(what, response) {
    var request;
    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
      request = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // IE
      try {
        request = new ActiveXObject('Msxml2.XMLHTTP');
      } catch (e) {
        try {
          request = new ActiveXObject('Microsoft.XMLHTTP');
        } catch (e) {}
      }
    }
    // state changes
    request.onreadystatechange = function() {
      if (request.readyState === 4) { // done
        if (request.status === 200) { // complete	
          response(request.responseText)
        } else response();
      }
    }
    request.open('GET', what, true);
    request.send(null);
  }
}
//PromiseAll
// @author loretoparisi at gmail dot com
var promiseAll = function(items, block) {
  var promises = [];
  items.forEach(function(item, index) {
    promises.push(function(item, i) {
      return new Promise(function(resolve, reject) {
        return block.apply(this, [item, index, resolve, reject]);
      });
    }(item, index))
  });
  return Promise.all(promises);
} //promiseAll

promiseAll([...new Array(3)], (item, index, resolve, reject) => {
    console.log("Making request [" + index + "]")
    SimpleRequest.call('https://icanhazip.com/', function(result) {
      if (result) {
        console.log("Response[" + index + "] " + result);
        resolve(result);
      } else {
        reject(new Error("call error"));
      }
    })
  })
  .then((results) => {
    console.log(results)
  })
  .catch((error) => {
    console.log(error)
  });

答案 1 :(得分:0)

这有效......来自https://stackoverflow.com/a/5627301/1459802的解决方案 更新的代码:     // JavaScript文档     $(&#34; [名称=领域]&#34)。每一(功能(){

        var student_id  = $(this).attr("data-student_id");
        var deferreds = [];
        ///////////////////////////////////////////////////////////////////
        deferreds.push( $.ajax({
            method: "POST",
            url: "/load.php",
            dataType: "html",
            async: true,
            beforeSend: function(){
            },
            data:   { 
                        //some data
                    },

            success: function( response ) 
            {   
                // dynamically add radio buttons
                // html response is radio buttons with NAME of as_xxxx inside of #container (parent element)
                $("[name=areas][data-student_id='"+student_id+"']").fadeIn( "slow").html(response).show();

            },
            error: function(xhr, textStatus, errorThrown)
            {
                // show error message
            }
        }) //END AJAX/////////////////////////////////////////////////////////////////
        );

    }); // .each


     $.when.apply(null, deferreds).done(function() {
          console.log("*************** DONE *****************");
         save_data();
        });    
});
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  SAVE
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function save_data()
{

    //$(document).on('click','#container [name^=as_]',function(event) // WORKS IF ajax ASYNC = TRUE

    $("[name=areas][name^=as_]").on("click",function(event)  // DOES NOT WORK IF ajax ASYNC = TRUE.   Works if ASYNC = FALSE
    {
        // SAVE RADIO BUTTON DATA ON CLICK
    });
}
</javascript>