Reputation: 121
I have a trivial problem that I'm eager to solve correctly, with jQuery 3. So the idea is this:
I currently I have something working. But the question is: Is this the correct or preferred way of doing it?
// helper function for setTimeout
function wait(ms) {
var deferred = $.Deferred();
setTimeout(function() { deferred.resolve() }, ms);
return deferred.promise();
}
var request = $.ajax({
dataType: "json",
url: "/api/articles/?" + $.param(params)
});
wait(500).then(function() {
if (request.state() === "pending") // works, but the docs says we should do this only for debugging purposes
$(".spinner").show();
});
request.always(function() {
$(".spinner").hide();
);
Can we use request.state()
this way? Could this have been solved in a more elegant way?
Upvotes: 1
Views: 1062
Reputation: 19288
You should really try to do things like this without synchronous inspection of promise state.
Fairly minor modifications to the code are required.
wait()
instead of a promise.wait(500)
and keep a reference to the returned Deferred.wait(500)
Deferred.wait(500)
Deferred on settlement of the ajax promise, thereby ensuring that the timeout can't resolve it later.This will effectively set up a race between the wait(500)
deferred and the $.ajax()
promise, the former trying to display the spinner and the latter trying to prevent it.
function delay(ms) {
return jQuery.Deferred(function(dfrd) {
setTimeout(dfrd.resolve, ms);
});
}
var showSpinner = delay(500); // a Deferred that will be resolved after 500ms, unless rejected before that.
showSpinner.then(function() {
$(".spinner").show();
}, function() {
console.log('The ajax request settled before the timeout');
});
jQuery.ajax({
dataType: 'json',
url: '/api/articles/?' + $.param(params)
}).always(function() {
$(".spinner").hide(); // hide spinner (if the timeout won the race)
showSpinner.reject(); // prevent the spinner from being shown
});
Upvotes: 2