问题
I Have a 2 JavaScript functions what call one after another. like following.
updateUI(event);
syncCall();
function updateUI(event) {
formSubmitBtn = $(event.target).find('[type=submit]:not(".disabled")');
formSubmitBtn.attr('disabled', 'disabled');
var loadingText = I18n.t('Submitting');
formSubmitBtn.val(loadingText).text(loadingText);
}
function syncCall(){
$.ajax({
async: false,
dataType: 'json',
type: 'GET',
url: '/calls/synccall',
success: function (json) {
userIsSignedIn = json.is_signed_in;
}
});
}
I am updating a UI element before sync ajax call. but UI changes are not showing. When I try to debug the code it works fine.
回答1:
I can imagine your code is doing something like
var userIsSignedIn;
updateUI(event);
syncCall();
nextThing(userIsSignedIn);
anotherThing();
moreThings();
With a simple change to syncCall - called asyncCall to be not confusing
function asyncCall(cb){
$.ajax({
dataType: 'json',
type: 'GET',
url: '/calls/synccall',
success: function (json) {
cb(json.is_signed_in);
}
});
}
your code re-written:
updateUI(event);
asyncCall(function(userIsSignedIn) {
nextThing(userIsSignedIn);
anotherThing();
moreThings();
});
Note the lack of var userIsSignedIn; required
Really a small change for improved end user experience
a second alternative is to wrap all the code you presented in a function tagged async
async function doThings() {
updateUI(event);
let userIsSignedIn = await ajaxCall(); // see below
nextThing(userIsSignedIn);
anotherThing();
moreThings();
}
and return a Promise from ajaxCall (what was syncCall)
function ajaxCall(){
return $.ajax({
dataType: 'json',
type: 'GET',
url: '/calls/synccall'
}).then(json => json.is_signed_in);
}
Run this through a transpiler (like babel) to produce code that should work on Internet Exploder and similarly "backward" browsers
Summary: In the end you have two choices
- Use async:false and have rubbish user experience
- embrace asynchrony and write code that befits the 21st century
回答2:
Call this function beforeSend like as follows
function syncCall(){
$.ajax({
async: false,
dataType: 'json',
type: 'GET',
url: '/calls/synccall',
beforeSend:function(){
updateUI(event);// Call here
}
success: function (json) {
userIsSignedIn = json.is_signed_in;
}
});
}
If above not work try following
updateUI(event);
function updateUI(event) {
formSubmitBtn = $(event.target).find('[type=submit]:not(".disabled")');
formSubmitBtn.attr('disabled', 'disabled');
var loadingText = I18n.t('Submitting');
formSubmitBtn.val(loadingText).text(loadingText);
syncCall();// Try calling here
}
function syncCall(){
$.ajax({
async: false,
dataType: 'json',
type: 'GET',
url: '/calls/synccall',
success: function (json) {
userIsSignedIn = json.is_signed_in;
}
});
}
来源:https://stackoverflow.com/questions/45429984/updated-ui-not-showing-before-sync-ajax-call