javascript - timing issues with jquery deferred -
this question distilled version of not asynchronous function executed jquery deferred.
we have 2 jsfiddles:
http://jsfiddle.net/xsdvx/1/ - here progress event not fired, despite calling notify() function.
http://jsfiddle.net/uxsbw/1/ - here progress event fired expected.
the difference 1 line of code:
settimeout(dfd.resolve,1);
versus
dfd.resolve();
questions are:
how .then catching .notify called before callback returns when delay resolve? think it. .then takes deferred object returned it's first parameter , creates new deferred object it, binding it's done progress , fail events. if notify called before deferred returned, how .then catching settimeout? (thanks https://stackoverflow.com/users/400654/kevin-b asking this)
can rid of
settimeout()
, still have progress callback fired?
made big refactor , here one final working example, progress monitoring.
now important parts.
- jquery deferreds not execute progress callbacks, after resolve has been called (with 1 exception). in example (without settimeout), deferred resolved, no chances run progress.
- do hooks of callbacks, progress ones, before trigger enything on final deferred. achieved passing final deferred (now beacon) execution function, after have populated it's triggers.
- i refactored api func executed deferred agnostic.
- this solution, uses closure of local (to reduce iterator function) deferred, inside memo.then function, in order continue execution chain.
edit: forgot first question. behavior achieved via means of closure (the dfd variable in "x" function).
the function "x" returns (after triggering notify event can processed, deferreds of execution chain have been created, , done, fail, progress hooks of "executepromisequeuesync" have been hooked).
also function of settimeout "closes" dfd in closure, can access variable despite "x" has returned. "then" call continues creating next deferred linked first one.
after js vm yields (it has not other things do), settimeout triggers it's associated function, (by means of closure) have access "closed" dfd variable. deferred resolved , chain can continue.
edit2: here refactored version adds support long executing, deferred supported functions, notify caller progress.
edit3: here another version, without underscore binding , jq-ui progressbar example.
by way idea complex app initialization routines.
source (of first version)
function executepromisequeuesync(queue, beacon){ var seed = $.deferred(), le = queue.length, last; beacon.notify(0); last = _.reduce(queue, function(memo, ent, ind){ var df = $.deferred(); df.then(function(){ console.log("dbg proggie"); beacon.notify((ind+1)/le*100); }); console.log("dbg hook funk "+ind); memo.then(function(){ console.log("dbg exec func "+ind); ent.funct.apply(null, ent.argmnt); df.resolve(); }); return df.promise(); }, seed.promise()); last.then(function(){ beacon.resolve(100) }); seed.resolve(); // trigger return beacon.promise(); } function x(){ // stuff console.log("blah"); } var promisesqueue = [], beacon = $.deferred(); promisesqueue.push({funct: x, argmnt:[]}); promisesqueue.push({funct: x, argmnt:[]}); promisesqueue.push({funct: x, argmnt:[]}); function montheprog(pct) { console.log('progress '+pct); } // first hook, exec beacon.then(function(){ console.log('success'); }, function(){ console.log('failure'); }, montheprog); // dance executepromisequeuesync(promisesqueue, beacon)
Comments
Post a Comment