Terry Zhou
Terry Zhou

Reputation: 15

Promise does not work on Node.js nested Async

I wrote many benchmark scripts in Node.js for different design of redis schema. I tried to run all benchmark functions in sequence order. I came across many async template on StackOverflow to solve this. Those templates work fine on simple async but my single benchmark function contained many nested async functions and, when I used those templates, the nested async functions run in order but whole benchmark in parallel. Here is the example:

A single benchmark result looks like this: single benchmark

When I run all benchmark with Promise template: many benchmark

Benchmark function looks like. Others have same structure:

async function CMbenchmark(redis,size,flag){
var time_stamp0;
var time_stamp1;
var time_stamp2;
redis.flushall().then(()=>{
//initialize data
time_stamp0 = performance.now();
  console.log("benchmark size: "+size);
  CMinitializeFakeData(redis,size)
}).then(()=>{
  time_stamp1 = performance.now();
  console.log("time for initialize data: "+size);
  console.log(time_stamp1-time_stamp0);
  searchEntryByBM(redis,"gender","male");
}).then(()=>{
  time_stamp2 = performance.now();
  console.log("time for search operation: ");
  console.log(time_stamp2-time_stamp1);
  redis.memory("stats").then(function(result){
    console.log(result[0]+": "+result[1]/1000000+"MB");
    console.log(result[2]+": "+result[3]/1000000+"MB");
  });
});
}

Some execution functions I have tries, many other variations look similar:

async function benchAll(){
  Promise.resolve(benchmark2(redis,size,0)).then(function(){
    return Promise.resolve(benchmark(redis,size,0));
  }).then(function(){
    return Promise.resolve(CMbenchmark(redis,size,0));
  });
}

async function benchAll2(){
  const result1 = await benchmark(redis,size,0);
  const result2 = await benchmark2(redis,size,0);
  const result3 = await CMbenchmark(redis,size,0);
}

referring to: How should I call 3 functions in order to execute them one after the other?. The callback chain also does not work. Other than looking for solution. I am also looking for explanation on why callback chain works on simple async but not nested async.


update:

After adding return to the promise according to the answer by @d-_-b, the issue still exist.

Upvotes: 0

Views: 93

Answers (1)

d-_-b
d-_-b

Reputation: 23161

You need to return the promise you want available in the next .then().

You're very close! each time you call .then(function(){...}) you should return some value so that the next .then() will receive it.

redis.flushall().then(()=>{
  //initialize data
  time_stamp0 = performance.now();
  console.log("benchmark size: "+size);
  return CMinitializeFakeData(redis,size)// <-- added return here
}).then(()=>{
  time_stamp1 = performance.now();
  console.log("time for initialize data: "+size);
  console.log(time_stamp1-time_stamp0);
  return searchEntryByBM(redis,"gender","male"); // <-- added return here
}).then(()=>{
  time_stamp2 = performance.now();
  console.log("time for search operation: ");
  console.log(time_stamp2-time_stamp1);
  redis.memory("stats").then(function(result){
    console.log(result[0]+": "+result[1]/1000000+"MB");
    console.log(result[2]+": "+result[3]/1000000+"MB");
  });
});

Upvotes: 2

Related Questions