title: Node.js: Making a call to asynchronous parent function from within asynchronous child function's callback
body: <p>I'm trying to call an asynchronous function (the 'child') from within another asynchronous function (the 'parent'). To make things complicated, the parent function exposes a dual API (callback + promise). This is done using the Q library's <em>defer()</em> and <em>nodeify()</em>, like so:</p>
  
  <pre><code>var parent = function(p_arg, callback) {
  
    var deferred = Q.defer();
  
    child(arg, function(err, cb_arg) {
      if(err)
        deferred.reject(err);
      else
        deferred.resolve(cb_arg);
    });
  
    //If a callback was supplied, register it using nodeify(). Otherwise, return a promise.
    if(callback)
      deferred.promise.nodeify(callback);
    else
      return deferred.promise;
  }
  </code></pre>
  
  <p>Note that the child function doesn't return a promise. Now depending on the value of the argument passed to the child's callback (cb_arg), I might decide to make a fresh call to parent, albeit with a modified argument (p_arg). How do I do this keeping in mind the dual nature of the parent's API?</p>
  
  <p>This is what I've been able to come up with so far:</p>
  
  <pre><code>child(arg, function(err, cb_arg) {
    if(err)
      deferred.reject(err);
    else if(cb_arg.condition) {
  
      /*Make a fresh call to parent, passing in a modified p_arg*/
      if(callback)
        parent(p_arg + 1, callback);
      else
        deferred.promise = parent(p_arg + 1);
        /*
          ^ Is this the correct way to do this?
          My goal is to return the promise returned by the fresh parent() call,
          so how about I just assign it to the current parent() call's deferred.promise?
        */
    } 
    else
      deferred.resolve(cb_arg);
  });
  </code></pre>
  
  <hr>
  
  <p><strong>UPDATE</strong>: Okay, I just had a moment of clarity regarding this problem. I now think that what actually needs to be done is the following:</p>
  
  <pre><code>child(arg, function(err, cb_arg) {
    if(err)
      deferred.reject(err);
    else if(cb_arg.condition) {
  
      /*Make a fresh call to parent, passing in a modified p_arg*/
      if(callback)
        parent(p_arg + 1, callback);
      else
        parent(p_arg + 1)
        .then(function(p_ret) {
            deferred.resolve(p_ret);
        }, function(p_err) {
            deferred.reject(p_err);
        });
    } 
    else
      deferred.resolve(cb_arg);
  });
  </code></pre>
  
  <p>This pattern seems to work for my particular use case. But do let me know in case there are any glaring async-related errors with this approach.</p>