Tuesday, 4 April 2017

Node.js: Sequential execution of asynchronous tasks

I have an array of objects similar to:

let builds = [
    { status: "Failed"},
    { status: "Completed"},
    { status: "Building"},
    { status: "Building"},
    { status: "Failed"},
    { status: "Cancelled"},
   ...
]

The number of elements will vary and the status of each would also vary, with a minimum array size of zero.

I need to write a function that would:

  • Iterate through the array to and look for any items with a status of Building
  • Update the status of those items to Cancelled
  • When there are no more occurrences of Building, push a new item in the array similar to: { status: "Building" }

The catch is that the array is stored in a MongoDB and hence each operation needs to be persisted to the DB in an asynchronous fashion. I am using Q promises for everything.

My attempt at doing this looks like this at the moment:

let count=0;  // Keep track of how many "builds" in "Building" state

module.getAllBuilds((builds) => {
    builds.forEach((build) => {
        if (build.status == "Building") {
             count++;
             module.cancelBuild(build)
             .then(() => {
                 if (!--count) {  // When counter is zero, all builds have been dealt with.
                     module.newBuild();
                     return;
                 }
              })
        }
     })
     module.newBuild();   // Get here if the build array is empty or no builds in "Building" state
})

I am using a count variable to track the number of entries in the Building status, much like a stack. When the stack is empty, then I proceed with creating the new build.

The trouble is that I have to call the module.newBuild() in one of two places depending whether or not any builds were in Building state.

Is there a better way to implement this?



via mstubbies

No comments:

Post a Comment