Dashboards & Visualizations

JavasScript SDK: Async.chain not running synchronously

kcepull2
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!

Get Updates on the Splunk Community!

Splunk Custom Visualizations App End of Life

The Splunk Custom Visualizations apps End of Life for SimpleXML will reach end of support on Dec 21, 2024, ...

Introducing Splunk Enterprise 9.2

WATCH HERE! Watch this Tech Talk to learn about the latest features and enhancements shipped in the new Splunk ...

Adoption of RUM and APM at Splunk

    Unleash the power of Splunk Observability   Watch Now In this can't miss Tech Talk! The Splunk Growth ...