NyoNor
NyoNor

Reputation: 199

How to execute array of tasks one by one in JS without promises and async await sugar?

Deeping down to javascript and node.js, figuring out how to call this kind of tasks collection one by one.

function a(callback) {
    setTimeout(() => {
        console.log('a');
        callback();
    }, 200);
}

function b(callback) {
    setTimeout(() => {
        console.log('b');
        callback();
    }, 100);
}

function c(callback) {
    setTimeout(() => {
        console.log('c');
        callback();
    }, 400);
}

function d(callback) {
    setTimeout(() => {
        console.log('d');
        callback();
    }, 50);
}

const collection = [a, b, c, d];

So at the end I want to see:

a
b
c
d

But without async, await keywords and promises.

Upvotes: 0

Views: 270

Answers (4)

NyoNor
NyoNor

Reputation: 199

function iterateSeries(collection, iteratorCallback, finalCallback) {
    const task = collection.shift();
    if (collection.length == 0) {
        return (() => task(finalCallback))();
    }
    task(() => {
        iteratorCallback();
        iterateSeries(collection, iteratorCallback, finalCallback);
    });
}

iterateSeries(collection, () => {
    console.log('Done!');
}, () => {
    console.log('Finished!')
})

Upvotes: 0

Gabcvit
Gabcvit

Reputation: 1488

Ok, so without async/await nor promises it would still possible to iterate through the collections recursively. I added the following code below yours:

const collection = [a, b, c, d];
var indexOfSelectedFunction = 0

function executeElementFromCollection(selectedFunction) {
  selectedFunction(() => {
    if(indexOfSelectedFunction < collection.length - 1) {
      indexOfSelectedFunction++
      executeElementFromCollection(collection[indexOfSelectedFunction])
    }
  })
}

function runCollection() {
  indexOfSelectedFunction = 0
  executeElementFromCollection(collection[indexOfSelectedFunction])
}

runCollection()

The solution may seem not simplified enough for some more advanced developers, but I really wanted to the keep the code understandable and didactic for you. Hopefully it helps :)

Upvotes: 1

spender
spender

Reputation: 120498

Here's a function that will do the trick:

function run(funcs) {
    if (funcs.length === 0) {
        return;
    }
    const [f, ...remainingFuncs] = funcs;
    f(() => run(remainingFuncs));
}
run(collection);

If your interest extends to TypeScript, here's the playground I wrote this in: Playground Link

Upvotes: 3

fayzzzm
fayzzzm

Reputation: 24

function a() {
  setTimeout(() => {
    console.log("a");
    collection.length && collection.pop()();
  }, 200);
}

function b() {
  setTimeout(() => {
    console.log("b");
    collection.length && collection.pop()();
  }, 100);
}

function c() {
  setTimeout(() => {
    console.log("c");
    collection.length && collection.pop()();
  }, 400);
}

function d() {
  setTimeout(() => {
    console.log("d");

    collection.length && collection.pop()();
  }, 50);
}

const collection = [a, b, c, d].reverse();

collection.pop()();

Don't judge the weird code that I've written. It just the one example of how this thing could be solved. You can refactor and separate the code into the pieces to make it readable.

Upvotes: 0

Related Questions