I'm using Meteor 1.* and Iron Router 1.*.
I'm using Node.js calls on the server side in Meteor, outside of a Meteor-method -- specifically inside a server side Iron Router route.
A portion of the code inside of the route looks similar to the following so far:
fs.mkdir(filebox, function (e) {
if(!e || e.code === 'EEXIST') {
fs.writeFile(file1, function (err) {
if (err) throw err;
fs.writeFile(file2, function (err) {
if (err) throw err;
fs.writeFile(file.3, function (err) {
if (err) throw err;
ExternalLibrary.do_something_(file1, function (err, buffer) {
if (err) throw err;
ExternalLibrary.do_something_(file2, function (err, buffer) {
if (err) throw err;
ExternalLibrary.do_something_(file3, function (err, buffer) {
if (err) throw err;
some_object = { first: file1, second: file2 }
ExternalLibrary.do_something_else_(some_object, function (err, buffer) {
if (err) throw err;
fs.readFile(file1, function (err, data) {
if (err) throw err;
res.write(data);
res.end();
});
});
});
});
});
});
});
});
} else {
console.log(e);
}
});
My problem is, I need to add even more calls to fs.write and the ExternalLibrary and further make these calls conditional.
It looks like I'm entering Callback hell.
On Callbacks
I know that Meteor uses Coroutines (or fibers, or continuations), but I don't know anything about how this works. And that within a Meteor-method we have the option of using Meteor.wrapAsync.
I've read some on Node.js Promises and Generators. And specifically I'm trying out the frozeman/q-meteor library.
Question
What is the best way to 'flatten' this tree and save myself from Callback hell? I want a solution that will allow for conditional method calls too. For example, I'm going to eventually need to add something like the following to the code example above:
if (some_condition === true) {
// call this method or node function
fs.writeFile(file4, function (err) {
fs.writeFile(file5, function (err) {
// do something
}
}
}
else {
// call this method or node function
fs.writeFile(file6, function (err) {
fs.writeFile(file7, function (err) {
// do something
}
}
}