简体   繁体   中英

Passing CallbackFunction as Parameter for Ajax-Request

I want to get content for my website asynchronously. Now that I have more than one requests for my server I thought it would be great to seperate the "conntection Stuff" into another function:

function conToServerAsync( url, postParams, func )
{
   var xmlHttp;
   if( window.XMLHttpRequest )
   {
      xmlHttp = new XMLHttpRequest();
   }
   else
   {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
   }
   xmlHttp.onreadystatechange = func;
   xmlHttp.open("POST", url, true);
   xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   xmlHttp.setRequestHeader("Connection", "close");
   xmlHttp.send(postParams);
}

Now I have this other function which is executing the "conToServerAsync" function like this:

function findSearchResult(value)
{
  conToServerAsync( "Classes/Async/liveSearch.php", "sVal="+value, function()
  {
    if(xmlHttp.readyState == 4 && xmlHttp.status == 200)
    {
    document.getElementById("searchResult").innerHTML = xmlHttp.responseText;
    document.getElementById("searchResult").style.border="1px solid #A5ACB2";
    }
  });
}

Now whats actually interesting about my case is that I've checked everything and every parameter that is passed in is valid. Then I tried to allocate the function that is given in the last parameter "conToServerAsync( "Classes...", "sVal..", function(){...}" directly to the onreadystatechange:

...
xmlHttp.onreadystatechange = function()
        {
            if(xmlHttp.readyState == 4 && xmlHttp.status == 200)
            {
            document.getElementById("searchResult").innerHTML = xmlHttp.responseText;
            document.getElementById("searchResult").style.border="1px solid #A5ACB2";
            }
      }

... and it works perfectly :S So definitly the error is about passing the function on a wrong way and I have no idea. Cos my case is that specific I made a own question about it.

Thank you for answering :)

You're trying to use xmlHttp from the callback, but it's out of scope. I suggest the following approach:

function conToServerAsync( url, postParams, func )
{
   var xmlHttp;
   if( window.XMLHttpRequest )
   {
      xmlHttp = new XMLHttpRequest();
   }
   else
   {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
   }
   xmlHttp.onreadystatechange = function() {
      if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
         func.call(xmlHttp, xmlHttp);
      }
   }
   xmlHttp.open("POST", url, true);
   xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   xmlHttp.setRequestHeader("Connection", "close");
   xmlHttp.send(postParams);
}

function findSearchResult(value)
{
  conToServerAsync( "Classes/Async/liveSearch.php", "sVal="+value, function(xhr)
  {
    document.getElementById("searchResult").innerHTML = xhr.responseText;
    document.getElementById("searchResult").style.border="1px solid #A5ACB2";
  });
}

On my implementation of the XMLHttp wrapper I use the Function.prototype.call to call the callback function from the XMLHttp Object scope, So you can use the keyword this to access properties and I also pass the responseText as a parameter for convenience.

if(typeof func=="function")
    func.call(xmlHttp, xmlHttp.responseText);

You can easily print the response on the callback

function callback(response){
    alert(response);
}

But you can still have access to all properties of the XMLHttp Object

function callback(response){
    alert(this.status); //200
    alert(response);
}

Full code:

function conToServerAsync( url, postParams, func ){

   var xmlHttp;
   if( window.XMLHttpRequest ){
      xmlHttp = new XMLHttpRequest();
   }
   else{
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
   }
   xmlHttp.onreadystatechange = function() {
      if(xmlHttp.readyState==4 && xmlHttp.status==200){
        if(typeof func=="function")
            func.call(xmlHttp, xmlHttp.responseText);
      }
   }
   xmlHttp.open("POST", url, true);
   xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
   xmlHttp.setRequestHeader("Connection", "close");
   xmlHttp.send(postParams);
}

function findSearchResult(value){

  conToServerAsync( "Classes/Async/liveSearch.php", "sVal="+value, function(response){
    document.getElementById("searchResult").innerHTML = response;
    document.getElementById("searchResult").style.border="1px solid #A5ACB2";
  });
}

Since the function you passed to xmlHttp.onreadystatechange is called with xmlHttp as the context you can use this to refer to that object.

function findSearchResult(value)
{
  conToServerAsync( "Classes/Async/liveSearch.php", "sVal="+value, function()
  {
    if(this.readyState == 4 && this.status == 200)
    {
    document.getElementById("searchResult").innerHTML = this.responseText;
    document.getElementById("searchResult").style.border="1px solid #A5ACB2";
    }
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM