The call to $.ajax()
is asynchronous, which means that the rest of the script will continue to execute immediately after the call is made, without waiting for the call to complete and trigger the success or error handlers.
This means that your function called callback
is being executed before your success handler. It may usually work as intended with a 3000ms timeout as your web service often takes less time than this to complete, so your callbacks are executed first in these cases. As you mentioned, this is not a reliable way to control the order of events.
One solution would be to execute your callback as part of the complete handler, as follows:
$(document).ready(function() {
var nextPage = "index.html",
storage = window.opener.sessionStorage;
function setStorage(callback){
$.ajax({
type: "GET",
cache: false,
dataType: "json",
url: "https://someserviceURL/service/profile",
success: function(objJSON){
//storage.op is set on the parent page when login or reg link is clicked
if (storage.op == "login") {
storage.firstname = objJSON.firstName;
storage.lastname = objJSON.lastName;
storage.setItem('loggedIn',JSON.stringify(true)); //Some browsers don't support booleans in sessionStorage
nextPage = "dashboard.html";
}
else if (storage.op == "register") {
storage.firstname = objJSON.firstName;
storage.lastname = objJSON.lastName;
storage.setItem('loggedIn',JSON.stringify(true));
nextPage = "options.html";
}
},
error: function( jqXHR, textStatus, errorThrown){
//display error message
},
complete: function( jqXHR, textStatus){
callback();
}
});
}
setStorage(function(){
if (typeof window.opener != "undefined" && window.opener != null){
window.opener.location.href = nextPage;
window.close();
}
});
});
Or if you don't care about the returned arguments you could pass callback
directly to complete
. Note that complete will be executed in both success and error conditions, so you might want to call callback only in your success handler and do something else with any errors.