Dashboards & Visualizations
Highlighted

JavasScript SDK: Async.chain not running synchronously

Path Finder

I'm writing JavaScript that will run inside of a SimpleXML dashboard in Splunk. In that JS, I'm looping through values in an array, and for each value, making a REST API call back to Splunk to delete a corresponding row from a KV store collection. I don't want an error to stop the looping, so I want to capture any errors and add them to an error array (of strings).

My pseudo-code is something like this:

console.log("# of values in 'lines' array: " + (lines.length+1));
for (i=0; i < lines.length; i++) { // 'lines' is the array of values to process
  splunkjs.Async.chain([
    function(done) {
      // Make a REST API call to delete the row from the KV collection, if present
      service.del("storage/collection/data/kv_collection_name/" + lines[i], null, done);
    },
    function(success, done) { // "success" function
      // if we get here, the row existed in the KV store. So, set the lines[i] to undefined to indicate it worked.
      lines[i] = undefined; 
      console.log("line " + i + " success!");
      done();
    } ],
    function(err) { // "error" function
      // if the value wasn't found in the KV store, this will get called. Print out the line # that failed.
      console.log("line " + i + " failed."); 
      // The previous line doesn't output the right value for 'i' - instead it outputs the value at that moment, which is 1 after the size of the 'lines' array (since the for loop is done)
    } );
  } // end of for loop
console.log("Done. Lines that failed = " + lines);

The problem I'm having is that while the Async.chain call appears to call the functions within it sequentially (e.g. waits for the call to service.del to finish before calling the "success" function OR the "error" function), It does NOT appear to wait for everything to finish before continuing with the 'for' loop, NOR the code after the for loop.

So, what I end up getting is that by the time the "success" or "error" function is called for a given iteration, the value of 'i' has already been incremented to the next value. So, I have no way of knowing WHICH input value in the 'lines' array succeeded or failed! And, the "Done. Lines that failed = ..." line is output to the console BEFORE any of the "Success" or "Failed" lines (and all of the lines are still in the array, since the "success" function in the for loop hasn't fired for valid ones yet).

Example output (assume first value is a success, and second fails):

# of values in 'lines' array: 2
Done. Lines that failed = ['line1', 'line2'] <- should output AFTER the below "success"/"failed" lines
line 2 success!  <- should be "line 0 success!"
line 2 failed.  <- should be "line 1 failed."

How can I make sure the calls within the Async.chain have actually finished before continuing with the for loop (or the code after it)? I've searched and searched, and can't seem to find any examples where there is code AFTER the async.chain command - all of the examples simply show what I have IN the for loop (print out "success" or "failure") and don't take into account any subsequent code that needs to be executed.

Thanks!