Will Luce Will Luce - 3 months ago 20
Javascript Question

Promises.all not fulfilling before function returns

I've been wrestling with this for a bit and I'm not sure of a next step. I'm trying to make am async DB call inside a

switch
statement. Now, I know it won't fulfill the promise in time if I put it inside the statement itself so I've created an array of the calls and am trying to resolve them all prior to building the object that gets returned. Right now, I'm just returning the empty array of
failed_tests
because
Promise.all
isn't finishing prior to building the object.

function getMetrics(num_tests, env)
{
return new Promise((fulfill, reject) =>
{
elastic.getMostRecentResults(num_tests, env).then(results =>
{
var promises = [];
var num_failed = 0,
num_passes = 0,
num_skipped = 0,
failed_tests = [];
results.aggregations.tests.buckets.forEach(bucket =>
{
switch(bucket.most_recent_result.hits.hits[0]._source.status)
{
case "passed":
num_passes++;
break;

case "skipped":
num_skipped++;
break;

case "failed":
num_failed++;
var full_id = bucket.most_recent_result.hits.hits[0]._source.full_id;
promises.push(getResultsForFailedTest(full_id, env));

break;

default:
break;
}
});

console.log(promises.length);

Promise.all(promises).then(results => {
failed_tests.push(results)
}).catch(err => {
console.log(err)
});

var metrics = {
"total_tests": num_tests,
"num_pass": num_passes,
"num_skip": num_skipped,
"num_fail": num_failed,
"failed_results": failed_tests
};

fulfill(metrics);
});
});
}

Answer

Change:

  Promise.all(promises).then(results => {
    failed_tests.push(results)
  }).catch(err => {
    console.log(err)
  });

  var metrics = {
    "total_tests": num_tests,
    "num_pass": num_passes,
    "num_skip": num_skipped,
    "num_fail": num_failed,
    "failed_results": failed_tests
  };

  fulfill(metrics);

to:

  Promise.all(promises).then(results => {
    failed_tests.push(results)
    var metrics = {
      "total_tests": num_tests,
      "num_pass": num_passes,
      "num_skip": num_skipped,
      "num_fail": num_failed,
      "failed_results": failed_tests
    };

    fulfill(metrics);
  }).catch(err => {
    console.log(err)
  });

Reason being, metrics is being created and fulfill is being called before the function within your .then statement is executed.