title: node.js chain multiple promises (with mongoose)
body: <p>The following is a typical promise function that I am dealing with.  </p>
  
  <pre><code>var _delete = function(t, id) { 
    return Promise.cast(Event.find({where: {id: id}}, {transaction: t}))
    .then(function(d){
      if (d) {
        // ------- (*)
        return Promise.cast(d.updateAttributes({status: -1}, {transaction: t}))
        .then(function(){
            // do inventory stuff 
            return Promise.cast(Inventory.update({}).exec())
            .then(function(d){
                 // do something 
            })
        }).then(function(){
            // do product stuff
            return Promise.cast(Product.update({}).exec())
            .then(function(d){
                 // do something 
            })
        })
      } else {
        return Promise.reject('this transaction list does not exist');
      }
    });
  };
  </code></pre>
  
  <p>This looks ok until when I am dealing with more complicated update / creates the code will become really messy. </p>
  
  <p>Currently what I am doing with promise is that
  1. I have a lot of useless return true statements and the only purpose is to go to next .then statement
  2. promise are programmed in a nested style. also the input arguments are usually complicated and has more then 1 arguments so that I cannot do something like this</p>
  
  <p><code>.then(fun1).then(fun2)</code></p>
  
  <p>... etc</p>
  
  <p>which makes me unable to <code>'tap'</code> the <code>.then</code> statement to enable/disable a functionality.  </p>
  
  <p>So my questions is how do I do this correctly?  Thanks..</p>
  
  <hr>
  
  <p>the following is the really ugly things that I am talking about....</p>
  
  <pre><code>var _process = function(t, tid) {
    var that = this;
    return Promise.cast(Usermain.find({where: {transaction_id: tid}}))
    .bind({})  // --- (*)
    .then(function(d){
      this.tmain = d;
      return true;   // ---- do nothing, just go to next thennable (is this correct)
    }).then(function(){
      return Promise.cast(Userlist.findAndCountAll({where: {transaction_id: tid}}))
    }).then(function(d){
      this.tlist = d;
      return true;  // ---- do nothing, just go to next thennable (is this correct)
    }).then(function(){
      if (this.tmain.is_processed) {
        return Promise.reject('something is wrong');
      }
      if (this.tlist.count !== this.tmain.num_of_tran) {
        return Promise.reject('wrong');
      }
      return Promise.resolve(JSON.parse(JSON.stringify(this.tlist.rows)))
      .map(function(d){
        if (d.is_processed) return Promise.reject('something is wrong with tran list');
        return true;  // goto next then
      });
    }).then(function(){
      return Promise.cast(this.tmain.updateAttributes({is_processed: 1}, {transaction: t}));
    }).then(function(){
      return Promise.resolve(this.tlist.rows)
      .map(function(d){
        var tranlist = JSON.parse(JSON.stringify(d));
        return Promise.cast(d.updateAttributes({is_processed: 1, date_processed: Date.now()}, {transaction: t}))
        .then(function(d){
          if (!d) {
            return Promise.reject('cannot update tran main somehow');
          } else {
              if (tranlist.amount &lt; 0) {
                return Usermoney._payBalance(t, tranlist.user_id, -tranlist.amount);
              } else {
                return Usermoney._receiveBalance(t, tranlist.user_id, tranlist.amount);
              }
            }
        });
      });
    });
  }
  </code></pre>