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 defer() and nodeify(), like so:
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;
}
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?
This is what I've been able to come up with so far:
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);
});
UPDATE: Okay, I just had a moment of clarity regarding this problem. I now think that what actually needs to be done is the following:
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);
});
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.