2

I have an array of function with async method inside it.I want to create a function which takes the array of function and execute the function in sequential order.I am not sure how to achieve it.Thanks for help.The functions are not async in nature.Its the method inside each functions

Example.

function task1() {
  console.log('task1:started');
  setTimeout(function() {
    console.log('task1:finished');
  }, 5000);
}

function task2() {
  console.log('task2:started');
  setTimeout(function() {
    console.log('task2:finished');
  }, 5000);
}

function runner(tasks) {
  // help with implementation needed
  console.log('Desired Output:');
  console.log('task1: started');
  console.log('task1: finished');

  console.log('task2: started');
  console.log('task2: finished');
}

8
  • 1
    Possible duplicate of Node.js: How to run asynchronous code sequentially Commented Feb 25, 2018 at 17:28
  • 2
    Without taking a callback or returning a callback, you'll have a hard time to know when such a task is finished Commented Feb 25, 2018 at 17:31
  • @suraj.tripathi . I can't use .then property on functions because they are not async in nature.its the method inside each function which is async in nature Commented Feb 25, 2018 at 17:33
  • 1
    @MarutiNandan you'll need to rewrite those functions to either take a callback or return a promise. Is that an option? Commented Feb 25, 2018 at 17:36
  • 2
    If these functions don't have any way of signaling when they are finished, there's not much you can do. This seems unusual since almost all async functions have some way - a callback, or promise - of letting you know they are finished. Commented Feb 25, 2018 at 17:38

1 Answer 1

3

Classic answer

You'll have to accept callbacks to achieve this, e.g.

runner([task1, task2], function() {
  console.log('tasks done!');
})

function task1(cb) {
  console.log('task1:started');
  setTimeout(function() {
    console.log('task1:finished');
    cb();
  }, 100);
}

function task2(cb) {
  console.log('task2:started');
  setTimeout(function() {
    console.log('task2:finished');
    cb();
  }, 100);
}

function runner(tasks, cb) {
  if (!tasks.length) {
    return cb();
  }

  let index = 0;

  function run() {
    var task = tasks[index++]

    task(index === tasks.length ? cb : run);
  }

  run();
}

Using async.waterfall

async.waterfall([task1, task2], function() {
  console.log('tasks done!');
})

function task1(cb) {
  console.log('task1:started');
  setTimeout(function() {
    console.log('task1:finished');
    cb();
  }, 100);
}

function task2(cb) {
  console.log('task2:started');
  setTimeout(function() {
    console.log('task2:finished');
    cb();
  }, 100);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/2.6.0/async.js"></script>


Promise-based implementation

runner([task1, task2]).then(() => {
  console.log('tasks done')
})

function task1(cb) {
  return new Promise(resolve => {
    console.log('task1:started');
    setTimeout(function() {
      console.log('task1:finished');
      resolve();
    }, 200);
  });
}

function task2(cb) {
  return new Promise(resolve => {
    console.log('task2:started');
    setTimeout(function() {
      console.log('task2:finished');
      resolve();
    }, 100);
  });
}

function runner(tasks, cb) {
  return tasks.reduce((job, task) => job.then(task), Promise.resolve());
}

Sign up to request clarification or add additional context in comments.

5 Comments

No need to make run, next and the anonymous callback three separate functions.
Not really, imo. You've also duplicated a lot of the code, like the tasks.length check. Also why would index++ not be inside next?
You are entitled to your opinion, I won't engage in discussion of actual or perceived stylistic issues. You are free to provide a superior implementation.
I didn't mean to start a discussion either, I just wanted to give a tip and a reason why I didn't upvote despite the otherwise great answer :-)
@Bergi: Revisited the callback example and optimized for brevity.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.