jQuery中的未定义变量

Through ajax call i am updating something and returning false and true. but the problem is that before i get result value from update function the if condition that is present after update function is executed and thus it give an error undefined result and errMsg variable. If I write this code again then it works. how i can stop running if condition until my update function returns some value?

var result = update(field_name, field_value);

if (result == false) {
  alert(errMsg);
} else {
  alert(errMsg);
}

update function

function update(field_name, field_value) {
  if (field_value) {
    $.post("/restapi/vc/users/id/${user.id}/profiles/name/" + field_name + "/set?value=" + field_value, function(data, status) {
      var xmlDoc = data;
      var x = xmlDoc.getElementsByTagName("response")[0];
      var txt = x.getAttribute("status");
      if (txt == 'error') {
        var msg = xmlDoc.getElementsByTagName("message")[0];
        var errMsg = msg.childNodes[0];
        window.errMsg = errMsg.nodeValue;
        return false;
      } else {
        return true;
      }
    });
  }
}

because update function returns a void/null. and null is == to false.

var result = update(field_name,field_value);
//update method is called and returns null 
if(result == false){  //null == false is true
    alert(errMsg);  //this line will execute
}else{
    alert(errMsg);
}

this is happening because of async nature of JavaScript. window.errMsg is being set after it is alerted. ajasx post in update method is a ajax request and its sucess method is called async.

better way withtout using Deffered would be to use callback.

var update = function update(field_name, field_value, callback) {
    if (field_value) {
        $.post(
            "/restapi/vc/users/id/${user.id}/profiles/name/" + field_name + "/set?value=" + field_value,
            function(data, status) {
                var xmlDoc = data;
                var x = xmlDoc.getElementsByTagName("response")[0];
                var txt = x.getAttribute("status");
                if (txt == 'error') {
                    var msg = xmlDoc.getElementsByTagName("message")[0];
                    var errMsg = msg.childNodes[0];

                    //its not good practice to add 
                    //transactional messages to window/global scope
                    //window.errMsg = errMsg.nodeValue;  

                    //return false;   
                    //instead of return call the callback
                    callback(errMsg.nodeValue);
                } else {
                    //return true;
                    //likewise in case of success
                    callback();
                }
            }
        );
    }
};

//and call update method like this -
update(field_name, field_value, function(errMsg){
    if (errMsg) {
        alert(errMsg);  //alert the error message
    } else {
        alert('success');
    }
});

There are two way to call update function after the ajax call

1) Call update function in response of the ajax call

2) Call Ajax as synchronous by setting async:false in ajax call

Link for more information synchronous on ajax call will be here How can I get jQuery to perform a synchronous, rather than asynchronous, Ajax request?

The problem here is that your if condition is executing before the ajax request is done. Ajax works asynchronously, meaning it executes in a background process and the main javascript execution doesn't wait for it to finalize to progress.

errMsg will never get the value from within the ajax callback since it will execute most probably before the ajax is done

You can simply alert the message from within the post callback function :

function update(field_name, field_value){
                 if(field_value){
                   $.post("/restapi/vc/users/id/${user.id}/profiles/name/"+field_name+"/set?value="+field_value, function(data, status){
                      var xmlDoc = data;
                      var x = xmlDoc.getElementsByTagName("response")[0];
                      var txt = x.getAttribute("status");
                       if(txt == 'error'){
                        var msg = xmlDoc.getElementsByTagName("message")[0];
                        var errMsg = msg.childNodes[0];
                        alert(errMsg); // alert the message here
                        } else{
                          return true;
                        }

                    });
                   }
               }

You can use $.Deferred like this:

function update(field_name, field_value){
  var defObj = $.Deferred();
  if(field_value){
         $.post("/restapi/vc/users/id/${user.id}/profiles/name/"+field_name+"/set?value="+field_value, function(data, status){


               defObj.resolve(data);
          });
   }
  return defObj.promise();

}

and you can get the data attribute here

var result = update(ield_name,field_value);

$.when(result).done(function(data){
  //  ....you will get the `txt` here..
  //    ... so move your above code here..
  var xmlDoc = data;
  var x = xmlDoc.getElementsByTagName("response")[0];
  var txt = x.getAttribute("status");
  if(txt == 'error'){
        var msg = xmlDoc.getElementsByTagName("message")[0];
        var errMsg = msg.childNodes[0];
        window.errMsg = errMsg.nodeValue;
        // other code goes here...
  }

});