A quick question on how to use Jquery.deferred to make a slow synchronous function return a promise instead. What I've done so far is this :
function sayIt(ms) {
setTimeout( function() { console.log('what I say'); }, ms);
}
function doIt() {
return $.Deferred( function() { sayIt(2000); }).promise();
}
doIt().then( function() { console.log('ah'); });
the sayIt(2000) always goes through but the chained function after the 'then' never fires.
If I do this :
doIt().then( console.log('ah'));
the 'ah' comes up right away, and then the 'what I say' 2000ms later - what I want is of course the opposite - that after two seconds I get 'what I say' and then 'ah' right after.
Any suggestions appreciated!
If you want to execute a function after the timeout has expired, you need to call
resolve()
on theDeferred
object from within the timeout expiration function:In this way you constrain the resolution of the
Deferred
object to the expiration of the timeout.To achieve what I believe is your intent:
The
.promise()
call is optional. It only restricts the available interface for callers: by returning aPromise
instead of the originalDeferred
object, the caller can only react to events, but not triggering them. Reference: http://api.jquery.com/deferred.promise/.Eventually, your original call:
Will output:
To do something synchronously, but still use a promise, do:
The effect is that you still get a promise, but that promise is already resolved, so any
.then()
which is subsequently registered on it proceeds immediately.The advantage of this pattern is that if you subsequently replace the synchronous code with something asynchronous the function still has the same external interface.