问题
I know that similar questions have been posted many times, however I've read many of them and can't find an answer to my problem.
I have a function that waits for an ajax request response. Many of you will ask why? Well, I'm using a Wizard Jquery Plugin which executes a function onLeaveAStepFunction
when a step is left, then the wizard goes to the selected step if the return value from onLeaveAStepFunction
is true; else it remains in the same step.
I'm doing this async: false
for waiting and it works, but this is a bad design. Also, I can't use a blockUI plugin.
How can I do this?
Some code:
Initializing the wizard:
$("#wizard").smartWizard({
onLeaveStep : onLeaveStepFunction,
});
Calling the ajax request:
function onLeaveStepCallback(obj, context) {
nextStep = sendForm();
}
The ajax request:
var nextStep = false;
$.ajax({
url : path,
type : "POST",
async : false,
data : $("#" + idForm).serialize(),
success : function(data) {
$("#" + idDiv).html(data);
nextStep = !$("#" + idHiddenErrores).val())
}
});
Omitting the attributes. Please help me.
回答1:
You could use the jQuery wait method. I took an example from docs page to highlight how you'd do it:
$.when( $.ajax( "/request.php" ) ).done(function( response ) {
// response argument resolved from ajax requests
// process any work after ajax call finishes
}
A link to docs page:
http://api.jquery.com/jquery.when/
回答2:
I'm doing this async: false for waiting and it works, but this is a bad design also I can't use a blockUI plugin.
Unless your wizard is better designed and supports async callbacks (e.g., promise-returning ones), async:false
is your only choice.
Consider switching to a different wizard, and don't forget to file a bug for the plugin that you're currently using.
回答3:
One hackish work-around is to do it before leaveStep. Perhaps on showStep:
var wizard_next_step;
$("#wizard").smartWizard({
onShowStep : function (obj, context) {
onLeaveStepFunction(obj, context, function(nextStep){
wizard_next_step = nextStep;
});
},
onLeaveStep : function () {
return wizard_next_step;
}
});
You'd also need to modify your onLeaveStepFunction
to accept a callback:
function onLeaveStepCallback(obj, context, callback) {
nextStep = sendForm(callback);
}
And your ajax function should then be:
$.ajax({
url : path,
type : "POST",
async : false,
data : $("#" + idForm).serialize(),
success : function(data) {
$("#" + idDiv).html(data);
callback( !$("#" + idHiddenErrores).val()) );
}
});
Now, it looks like you're drawing into the wizard window with this:
$("#" + idDiv).html(data);
I'm entirely sure if this is the case. But if it is then you cannot do this here (obviously because it's onShowStep
which would overwrite current content). If this is so you should pass the data in the callback:
success : function(data) {
callback( data , !$("#" + idHiddenErrores).val()) );
}
Write the wizard like this:
var wizard_next_step;
var wizard_data;
$("#wizard").smartWizard({
onShowStep : function (obj, context) {
onLeaveStepFunction(obj, context, function(data, nextStep){
wizard_data = data;
wizard_next_step = nextStep;
});
},
onLeaveStep : function (obj, context) {
$("#" + idDiv).html(wizard_data);
return wizard_next_step;
}
});
The key is to call all the asynchronous functions and get the data long before you call all your synchronous functions.
Note: I don't know smart-wizard at all and not a serious jQuery user. The answer above is based on my 2 minutes reading smart-wizard documentation on github and my understanding of javascript. You will definitely need to modify my examples to make it work.
来源:https://stackoverflow.com/questions/25756226/waiting-for-ajax-response-same-function