John John
John John

Reputation: 1465

Implementing sequential callback execution

I am trying to execute following array (avoid callbackHell) of functions(sync/async), in a sequential order, implementing function runCallbacksInSequence (I need to implement my own function to understand how callbacks work and avoid using Async.js).

I do not quite understand how callbacks work that is why I am doing this exercise. Here is what I have so far. The function runCallbacksInSequence works well but I am having hard time to implement callback (null, result) signature. At the moment it follows callback (result) signature.

If you have any ideas let me know what I am doing wrong and how I can fix it.
- no promises and async/await

function first(cb) {
  setTimeout(function() {
    console.log('first()');
    cb('one');
    // cb(null, 'one');
  }, 0);
}

function second(cb) {
  setTimeout(function() {
    console.log('second()');
    cb('two');
    // cb(null, 'two');
  }, 100);
}

function third(cb) {
  setTimeout(function() {
    console.log('third()');
    cb('three');
    // cb(null, 'three');
  }, 0);
}

function last(cb) {
  console.log('last()');
  cb('lastCall');
  // cb(null, 'lastCall');
}

function runCallbacksInSequence(fns, cb) {
  fns.reduce((r, f) => k => r(acc => f(x => k([...acc, x]))), k => k([]))(cb);
}

const fns = [first, second, third, last];

runCallbacksInSequence(fns, results => {
  console.log('-- DONE --');
  console.log(...results);
});

Upvotes: 1

Views: 158

Answers (2)

Jonas Wilms
Jonas Wilms

Reputation: 138307

In your runCallbacksInSequence you first of all have to move the x to the second position, also for consistency the final callback should be called with its first argument being null:

 function runCallbacksInSequence(fns, cb) {
   //                                    v  v                                  vvvvvvvv
   fns.reduce((r, f) => k => r(acc => f((e, x) => k([...acc, x]))), k => k([]))(r => cb(null, r));
 }

If you want the first callback with an error (having the first argument set) to directly terminate the chain, you can extend your chain a bit:

 //                                              vvvvvv
 fns.reduce((r, f) => k => r(acc => f((e, x) => e ? cb(e) : k([...acc, x]))), k => k([]))(r => cb(null, r));

Upvotes: 2

weegee
weegee

Reputation: 3399

To answer I do not quite understand how callbacks work
A callback is a function that is to be executed after another function has finished executing. For example.

function run(cb){
  console.log("run")
  cb("okay it is running");
}

A simple function that logs stuff. How do you run it?

run()

But you want to receive the callback. To know that above cb() everything was done. You do this.

run((arg) => {
  console.log(arg) //logs "okay it is running"
});

What you actually got is a "call", "back" from the function you ran, while running it.

Upvotes: 1

Related Questions