In my opinion, deferreds/promises (as you have mentionned) is the way to go, rather than using timeouts.
Here is an example I have just written to demonstrate how you could do it using deferreds/promises.
Take some time to play around with deferreds. Once you really understand them, it becomes very easy to perform asynchronous tasks.
Hope this helps!
$(function(){ function1().done(function(){ // function1 is done, we can now call function2 console.log('function1 is done!'); function2().done(function(){ //function2 is done console.log('function2 is done!'); }); }); }); function function1(){ var dfrd1 = $.Deferred(); var dfrd2= $.Deferred(); setTimeout(function(){ // doing async stuff console.log('task 1 in function1 is done!'); dfrd1.resolve(); }, 1000); setTimeout(function(){ // doing more async stuff console.log('task 2 in function1 is done!'); dfrd2.resolve(); }, 750); return $.when(dfrd1, dfrd2).done(function(){ console.log('both tasks in function1 are done'); // Both asyncs tasks are done }).promise(); } function function2(){ var dfrd1 = $.Deferred(); setTimeout(function(){ // doing async stuff console.log('task 1 in function2 is done!'); dfrd1.resolve(); }, 2000); return dfrd1.promise(); }