Promise-driven animation Inspired by this question on Stack Overflow, I've attempted to code such animation, mostly to get some more practice with async, promises and Q.js:

(Live demo)

function addOutput(s) {
  $('&lt;div&gt;').text(s).appendTo(wnd);
  //return Q.defer().promise;
  return Q.delay(100).then(function() { return addPrompt(); });
}

function addInput(s) {
  var l = $('.prompt:last');
  return addLettersRecursive(l, s);
}

function addPrompt() {
  var prompt = "kos@codepen % ";
  var l = $('&lt;div&gt;').text(prompt).addClass('prompt').appendTo(wnd);
  return Q.delay(900);
}

function addLettersRecursive(container, s) {
  container.append(s.charAt(0)); // dangerous :(
  var row_complete = Q.defer();
  Q.delay(100).then(function() {
    if (s.length &lt;= 1) {
      Q.delay(300).then(function() {
        row_complete.resolve();
      });
    }
    addLettersRecursive(container, s.substr(1)).then(function() {
      row_complete.resolve();
    })
  });
  return row_complete.promise;
}

// Usage

addPrompt("&gt;&gt;&gt; ")
.then(function() { return addInput("whoami"); })
.then(function() { return addOutput("kos"); })
.then(function() { return addInput("uname -a"); })
.then(function() { return addOutput("Javascript in codepen.io, powered by Q.js"); })
.then(function() { return addInput("raz dwa"); })
.then(function() { return addOutput("zsh: command not found: raz"); })
.then(function() { return addInput("trzy cztery"); })
.then(function() { return addOutput("zsh: command not found: trzy"); })
.done();


I'm not really satisfied by this implementation, though. How can I simplify it? Here are the specific concerns I have:


I implemented addInput in terms of a recursive helper function addLettersRecursive which still is overly complicated according to my gut feeling.
There's this .then(function() { return function_that_returns_promise(args); }); pattern all over, which seems like a very verbose way of chaining behaviour. 


What I have tried:


I attempted to unwind the recursion by stacking the promises one on top of another in a loop, which was a bit tricky to implement because of the selective closure involved. There's some improvement but still looks messy:

function addInput(s) {
  var container = $('.prompt:last');
  var d = Q.delay(0);
  for (var i=0; i&lt;s.length; ++i) {
    d = d.then(function(i) { return function() { // pass i by value
      container.append(s.charAt(i));
      return Q.delay(100);
    }}(i));
  }
  return d.then(function() { return Q.delay(300); });
}

I'm not sure if this kind of pattern is typical to promise-driven code, or I'm just doing something sub-optimally. One thing that came to my mind is this substitution:

  /* before */ .then(function() { return addInput("whoami"); })
  /* after  */ .then(addInput.bind(null, "whoami"))

  /* before */ return d.then(function() { return Q.delay(300); });
  /* after  */ return d.then(Q.delay.bind(Q, 300));


Is it a good track?


Generally I haven't seen much "real life" uses of promises yet except the book cases, so if anything else looks out of the ordinary or sub-optimal, please raise it.
This stuff is hard to get right, at this point good promise driven code seems more like an art than engineering.

From a CodeReview perspective, your code is fairly easy to follow, except for one thing which got me stumped for a little while, row_complete should really be named char_complete, and then suddenly addLettersRecursive will make more sense.

There are at least 3 additional ways you can deal with .then(function() { return function_that_returns_promise(args); });


Change your functions ( like addInput ) to return a function, like this:

function addInput(s) {
  return function addInputWrapper(){
    var l = $('.prompt:last');
    return addLettersRecursive(l, s);
  }
}


Then you can call simply .then( addInput( 'whoami' ) )
Create a generic wrapper function like this:

function wrap( f ){
  var args = Array.prototype.slice.call(arguments,1);
  return function wrapper(){
    return f.apply( this, args );
  }
}


Then you can call .then( wrap( addInput, 'whoami' ) )
Generate a lambdafy function like this : 

function lambdafy( f )
{
  var lambda = function(){
    var args = Array.prototype.slice.call(arguments);
    return function(){
      f.apply( this , args );
    }
  }
  return lambda;
}


Then you can addInput = lambdafy( addInput ) and .then( addInput( 'whoami' ) )