Complex Q promise: one promise creates an array of other promises

I have an http request that should return a list of tasks. However, those tasks are generated in a complex fashion. This is how it works.

  1. Get all current tasks from the DB
  2. expire tasks that are old
  3. get user profiles from the DB
  4. if the user doesn't have a profile and a task for creating the profile doesn't exist, add a task for creating the profile
  5. additionally, for every subprofile the user has, make a daily task and save it to the DB, if a daily task hasn't already been created.
  6. return all the tasks to the HTTP caller

I'm listing this all here, in case there's a better way to do it. From what I understand, I should have promises for both the DB calls that are then followed by promises that manipulate the task/profile data.

What I don't understand is how to add the N promises that are needed for daily tasks into my promise chain. I also need all the data available the final process to return the newly created list of tasks. Should I be nesting promises somehow?

Currently, I imagine it being something like this:

var taskPromise = dbPromise(serverName, taskRequest, params);
var profilesPromise = dbPromise(serverName, profilesRequest, params);

Q.all([taskPromise, profilesPromise])
.then(function(arrayOfTasksAndProfiles){
           //do calculations and create an object like {tasks:[], profile:profile, subprofiles:[]})
.then(function(currentDataObject) {
          var deferred = Q.defer();
          var newTasksToBeCreated = // make a list of all the new tasks I want to create
          var promisesForNewTasks = [] // create an array of promises that save each of the new tasks to the server
          Q.all(promisesForNewTasks)
          .then(function(returnedIDsForNewTasks) {
                   // somehow match the returned IDs to the newTasksToBeCreated and add them on
                   currentDataObject.newTasks = newTasksToBeCreated
                   deferred.resolve(currentDataObject);
                 });)
.then(function(currentDataObject) {
          // now that the currentDataObject has all the tasks from the DB, plus the new ones with their IDs, I can respond with that information
          res.json(currentDataObject))
.done();

I have to make multiple calls to the DB to create new tasks, and I need to return those appended to the other tasks I received from the DB, and the only way I can see to do that is to nest a Q.all() call.

"There's gotta be a better way."

Only one thing: Don't create a custom deferred that you need to manually resolve. Instead, just return from the then handler; and return the resulting promise of the .then() call.

.then(function(currentDataObject) {
    var newTasksToBeCreated = // make a list of all the new tasks I want to create
    var promisesForNewTasks = [] // create an array of promises that save each of the new tasks to the server
    return Q.all(promisesForNewTasks)
//  ^^^^^^
    .then(function(returnedIDsForNewTasks) {
         // somehow match the returned IDs to the newTasksToBeCreated and add them on
         currentDataObject.newTasks = newTasksToBeCreated
         return currentDataObject;
//       ^^^^^^
     });
})

Else, it looks quite fine. If you have problems matching the returned ids to the tasks - don't do it that way. Instead, make each of the promisesForNewTasks resolve with its own task object (combined with the id?).