user3601166
user3601166

Reputation: 127

Bluebird promise on array of functions

I have an array of functions that need to be read from a JSON file: "functionArray" : ["task1()", "task2()", ... , "taskN()"]

My requirement is to call these tasks sequentially so that task2 function is called only after task1 function executes successfully. The wrapper that will make use of these functions will have function definition.


function task1(){ console.log('Inside task1'); }

function task2(){ console.log('Inside task2'); }

var functionArrayToBeUsed = readFromJson(functionArray);

\\functionArrayToBeUsed has all tasks that need to be finished


What will be an ideal way to do this using Promises.

Upvotes: 1

Views: 416

Answers (2)

Roamer-1888
Roamer-1888

Reputation: 19288

Assuming the JSON to be served in the form ...

"functionArray" : ["task1", "task2", ... , "taskN"]

... and the tasks to be properties of a tasks object ...

var tasks = {
    task1: function () {
        console.log('Inside task1');
    },
    task2: function () {
        console.log('Inside task2');
    }
};

... then you can do as follows.

Synchronous tasks

var functionArray = readFromJson(functionArray);
functionArray.reduce(function(previousResult, taskName) {
    return tasks[taskname](previousResult);
}, null);

Asynchronous (or mixed) tasks

var functionArray = readFromJson(functionArray);
functionArray.reduce(function(p, taskName) {
    return p.then(tasks[taskname]);
}, Promise.resolve());

In both cases, array method .reduce() provides a compact way to build a .then() chain, seeded with a resolved promise to get things started.

These examples give you more than you asked for. In each approach, a result is passed through from each function to the next. If the functions don't accept any params, then this feature will do no harm.

That said, everything would need to be more defensively coded if any of the functions was likely to return undefined.

Upvotes: 1

Artem
Artem

Reputation: 1870

Something like this (not tested):

function callSequentaly(promises) {
    var values = [];
    var newPromises = [];

    function makeSequence(prevPromise, nextPromise) {
        return prevPromise.then(function (value) {
            values.push(value);
            return nextPromise;
        });
    }

    newPromises.push(promises[0]);
    for (var i = 1; i < promises.length; i++) {
        newPromises.push(makeSequence(newPromises[i - 1], promises[i]));
    }

    var defer = Promise.defer();

    Promise.all(newPromises)
        .then(function () { defer.resolve(values) })
        .catch(function (e) { defer.reject(e) });

    return defer.promise;
}

Upvotes: 0

Related Questions