Javascript/jQuery: control execution order (no ajax/php yet) -
i spent hours reading posts on web controlling execution order in javascript/jquery, still don't understand.
i'm trying write code shows execution progress of behind-the-scenes javascript on webpage. have jsfiddle (http://jsfiddle.net/wlandau/9sbu9myb/) accomplishes using timeouts. javascript is
var showprogress = function(x){ $(".progress").hide(); $(x).show(); } var step1 = function(){ showprogress(".running"); }; var step2 = function(){ for(var = 0; < 1000000000; ++i) = + 1; }; var step3 = function(){ showprogress(".done"); }; $(".begin").click(function(){ step1(); settimeout(step2, 0); settimeout(step3, 0); }); $(".clear").click(function(){ $(".progress").hide(); });
i need use ajax , php, , i've read recommended tools when/then, deferred objects, , promises. tried (http://jsfiddle.net/wlandau/an8moww6/), execution order wrong. (the html page doesn't "running..." when loop running.) fiddle's javascript is
var showprogress = function(x){ $(".progress").hide(); $(x).show(); } var step1 = function(){ var def = $.deferred(); showprogress(".running"); return def.promise(); }; var step2 = function(){ var def = $.deferred(); for(var = 0; < 1000000000; ++i) = + 1; return def.promise(); }; var step3 = function(){ var def = $.deferred(); showprogress(".done"); return def.promise(); }; var success = function(){ console.log("success") }; var failure = function(){ console.log("failure") }; $(".begin").click(function(){ $.when(step1(), step2(), step3()).then(success, failure); }); $(".clear").click(function(){ $(".progress").hide(); });
question 1 (first fiddle): when change "step1()" "settimeout(step1, 0)" in "$(".begin").click(function(){..}" block, execution order breaks down. why this?
question 2 (second fiddle): why execution order wrong when try use when/then/deferred/promise?
question 3 (second fiddle): why isn't "success" function executing? told print console, chrome's javascript console shows nothing.
why timing wrong when try use when/then/deferred/promise (second fiddle)?
because don't have used settimeout
s, executing synchronously. browser won't re-render screen until has finished processing, , see done
appear in end.
using promises/deferreds doesn't make code asynchronous! have take care of yourself:
function step…(){ var def = $.deferred(); settimeout(function() { … }, 0); return def.promise(); };
also, calling step1(), step2(), step3()
@ once (and passing promises $.when
wait until resolved) run async functions in parallel, not want. chain them, use
step1().then(step2).then(step3).then(success, failure);
why isn't "success" function executing (second fiddle)?
because promises never resolved. when have finished asynchronous task, need tell deferred (and typically pass result value). promises had in code pending forever, never executing handlers.
fixed:
function step1() { var def = $.deferred(); settimeout(function() { showprogress(".running"); def.resolve(); }, 0); return def.promise(); } function step2() { var def = $.deferred(); settimeout(function() { for(var = 0; < 1000000000; ++i) = + 1; def.resolve(); }, 0); return def.promise(); } function step3() { var def = $.deferred(); settimeout(function() { showprogress(".done"); def.resolve(); }, 0); return def.promise(); }
since functions not inherently asynchronous, might choose action right away , put settimeout(def.resolve, 0)
, delay handlers; might both.
Comments
Post a Comment