If I understand Steps 1,2,3 correctly, then the logic you want can be coded something like this :
$(function() {
function validateInventory(form) {//`form` is passed conventionally at the left hand end of the pipe chain.
var dfrd = $.Deferred();//A Deferred object to be resolved/rejected in response to ajax success/error.
var params = .....;//use values from `form` as required
$.ajax({
type: "POST",
url: posturl + "?" + params,
dataType: "json"
}).done(function(res) {//ajax success
if(res.success || confirm(msg1)) { dfrd.resolve(form); }//Here we resolve dfrd, passing `form` in order to make `form` available to the next function in the pipe chain.
else { dfrd.reject("validateInventory() failed (not verified)"); }//Application error. By rejecting with a specific message, we have the means of knowing where the failure occurred.
}).fail(function(jqXHR, textStatus, errorThrown) {//ajax error
dfrd.reject("validateInventory() failed (textStatus)");//Again, a specific message.
});
return dfrd;
}
//Similar logic as inside validateInventory()
function preValidateUrls(form) {//The form, is piped through by the statement `dfrd.resolve(form);` in validateInventory
var dfrd = $.Deferred();
var params = .....;
$.ajax({
type: "POST",
url: posturl + "?" + params,
dataType: "json"
}).done(function(res) {
if(res.success || confirm(msg2)) { dfrd.resolve(form); }
else { dfrd.reject("preValidateUrls() failed (not verified)"); }
}).fail(function(jqXHR, textStatus, errorThrown) {
dfrd.reject("preValidateUrls() failed (textStatus)");
});
return dfrd;
}
//This is the function to be called if the various stages of validation were successful.
function overallSuccess(form) {
form.submit();
}
//This is a common error handler, which will be called if either of the validation stages fail.
function errorHandler(message) {
alert(message);//or whatever
}
var myForm = $("form").get(0);//for example
//And now the glue that puts the component parts together.
validateInventory(myForm).pipe(preValidateUrls, errorHandler).pipe(overallSuccess, errorHandler);
});
untested
For explanation, see comments in code.
The whole thing can be factored any number of different ways. I would choose to code it as above because the component parts are separate and clear, and the "glue" statement (the pipe chain) is very concise and easy to extend to accommodate further validation steps. With other approaches, you tend to get deep nesting of functions which is hard to follow, especially for someone who has to maintain the code in the future.