1

Possible Duplicate:
How do you make javascript code execute *in order*

var cek = false;

function checkForm()
{
    var user = document.forms["LoginForm"]["user"].value;
    var pwd = document.forms["LoginForm"]["pwd"].value;
    AJAXfunc("checkidpass.php?id="+user+"&pass="+pwd,function()
    {
        if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200))
        {
            $("#LoginRes").html(xmlhttp.responseText);
            if (xmlhttp.responseText == "")
                cek = true;
        }
    }); //---> 1

    return cek; //---> 2
}

I want to ask why "return cek;" (part 2) is executed before the AJAXfunc (part 1)? And I want to know how to make it executed in the right order.

Thanks for your help !

James Hill
  • 60,353
  • 20
  • 145
  • 161

4 Answers4

2

To understand your issue, you need to understand asynchronous methods. A simple google will give you a plethora of reading material. I suggest starting here:

Mastering Ajax, Part 2: Make asynchronous requests with JavaScript and Ajax

Hint: What you're doing now will never work - unless you choose to make it a synchronous function (not recommended).

James Hill
  • 60,353
  • 20
  • 145
  • 161
  • `Hint: What you're doing now will never work` Not even if you modify `AJAXfunction`s [`open`s](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#open%28%29) 3rd parameter to `false`? :o – Paul S. Jan 17 '13 at 15:43
  • @PaulS., I thought it best to avoid the synchronous vs async discussion and point the OP to resources that would teach the root cause of the problem. Based on your comment however, I've updated my hint. My original statement was correct though, what they are doing right now will never work. – James Hill Jan 17 '13 at 15:49
0

That's because the AJAX call is asynchronous.

The AJAXfunc call is executed before the return statement, but the anonymous function that you provide in the AJAXfunc call is called later.

The way to make the callback run before the return statement is to make the AJAX call synchronous. However, that is genrally not a good idea, as that will make the browser freeze while it is waiting for the response.

The usual way to handle this is to use a callback in the checkForm function:

function checkForm(callback) {
  var user = document.forms["LoginForm"]["user"].value;
  var pwd = document.forms["LoginForm"]["pwd"].value;
  AJAXfunc("checkidpass.php?id="+user+"&pass="+pwd,function() {
    if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) {
      $("#LoginRes").html(xmlhttp.responseText);
      callback(xmlhttp.responseText == "");
    }
  });
}

Usage:

checkForm(function(cek) {
  if (cek) {
    // ok
  } else {
    // not ok
  }
});
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • what happens if `xmlhttp.readyState != 4`? your callback will never be called! – drinchev Jan 17 '13 at 15:43
  • @drinchev: Yes, that state isn't handled in the original code either. The result would be (if it had worked) that the variable would be undefined. – Guffa Jan 17 '13 at 15:46
  • Yes it will be undefined, but your `checkForm(function(cek) { if ( cek ) { // ok } else { // this will never be called } });` right? – drinchev Jan 17 '13 at 15:48
  • @drinchev: Yes, it will. If the server returns something other than an empty result, it will be called. It's only if the server call fails that the callback won't be called, as the AJAX code doesn't handle errors. – Guffa Jan 17 '13 at 16:40
0

Javascript is async so async functions like you AJAXfunc doesn't block your program until it completes. That's why events and callbacks are heavily used in javascript.

e.g. your code with callbacks would look something like :

function checkForm(callback)
{
    var user = document.forms["LoginForm"]["user"].value;
    var pwd = document.forms["LoginForm"]["pwd"].value;
    AJAXfunc("checkidpass.php?id="+user+"&pass="+pwd,function()
    {
        if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200))
        {
            $("#LoginRes").html(xmlhttp.responseText);
            if (xmlhttp.responseText == "")
                return callback(true);
        }
        return callback(false);
    }); 
}

checkForm( function (result) { 
    var cek = result;
    // Rest of your code for manipulating DOM or something else where you need cek.
} );
drinchev
  • 19,201
  • 4
  • 67
  • 93
0

You best re-structure your code to trigger a callback when you get the response.

ie. 1. make checkForm have a callback argument 2. activate that callback with the result 3. have the rest of the code in the callback instead of following the return of the function

for example:

// before (wrong):
result = checkForm();
handleResult1(result);
handleResult2(result);

// after (correct):
checkForm(function(result) {
    handleResult1(result);
    handleResult2(result);
}
Iftah
  • 9,512
  • 2
  • 33
  • 45