I'm using the Q node library for Promises, question I think can apply to the Bluebird lib as well.
Context
I have a few function calls to make to both my own custom functions and node.js fs
style async functions.
if I'm making a call to a function like this:
sync function
do_something = function (input) {
// assign variables, do other sync stuff
}
and need the above to take place before
this function:
sync function
do_something_else = function (input) {
// assign variable, do other sync stuff
}
and then
need to call a native node function similar to:
async function
writeData = function (obj, callback) {
var deferred = Q.defer();
fs.writeFile(obj.file, obj.datas, function (err, result) {
if (err) deferred.reject(err);
else deferred.resolve('write data completed');
});
return deferred.promise.nodeify(callback);
}
and finally
need the above to take place before
this function:
sync function
do_something_last = function (input) {
// assign variable, do other sync stuff
}
Question
Is the 'right' thing to do here, to make all my functions 'deferred' or promise aware so I can make sure that they are called in sequence or in the correct order? like so:
do_something(variable)
.then(do_something_else)
.then(writeData)
.then(do_something_last)
.done();
or should I just do this instead and keep the ordering (sequencing)? Like so:
var variable1 = 'test1.txt'
var variable2 = 'test2.txt'
var return_value = do_something(variable1);
var return_another_value = do_something_else(return_value); <--sync
writeData(return_another_value); <-- async function
var final_value = do_something_last(variable2); <-- sync function
// could potentially have async calls again after a sync call
writeDataAgain(return_another_value); <-- async function
Clarifications
What I thought was since some of these sync functions are going to need to be fired after the async, I needed to make them Promise aware in order to keep the sequence straight, like so:
sync functions made promise aware
do_something = function (input) {
var deferred = Q.defer();
// assign variables, do other sync stuff
deferred.resolve(_output_result_);
return deferred.promise;
}
do_something_else = function (input) {
var deferred = Q.defer();
// assign variables, do other sync stuff
deferred.resolve(_output_result_);
return deferred.promise;
}
do_something_last = function (input) {
var deferred = Q.defer();
// assign variables, do other sync stuff
deferred.resolve('completed workflow');
return deferred.promise;
}
this would allow me to do this:
do_something(variable)
.then(do_something_else) <-- these need to execute before writeData
.then(writeData) <-- a async node fs call to writeFile
.then(do_something_last) <-- I need this to happen after the writeDate
.done();
After the feedback i've read, i guess what it seems like i'm really asking is:
How do I create a function workflow, mixing non-promise sync and promise-aware async function calls, all the while keeping the ordering (or sequencing) of execution?
Well, that simply won't work, as
do_something_last
is not called after thewriteData(…)
promise is resolved. It'll just start right after the promise is created and returned. So if you care about that particular order and want to wait until the data is written, then you need to usethen
with a callback:The general rules are:
You can just place synchronous functions in a
then
chain, non-promise return values (or even thrown exceptions) work fine in them. So while you can write your sequence likeit looks rather odd. If you don't plan to make the
do_something
s asynchronous in the near future for some reason, it's often simpler to write and readAdmittedly, it's sometimes more appealing to write
than
even though they are functionally identical. Choose the style that you like better and that is more consistent.
If all you care about is whether your functions go in sequence or not, then do this:
You'd only assign promises to variables when you're going to be passing those variables around (e.g. to other services), or using them to create different promise chains.
e.g