Broccoli
Synchronously execute promises

Dec 2016

Sometimes you need to execute promises synchronously. This is a little tricky as promises will start executing as soon as they are created and, if you create a bunch of them, they will run in parallel.


I created a tiny module to execute an array of promises synchronously: synchronous-octo-broccoli. It's pretty simple, all I'm doing is:

  1. Chaining an array of promises together, calling the next one after the current one has resolved
  2. Wrapping the promise declarations in functions, so that they are not executed until we need them

Here's an array of functions, which return promises:

let testString = '';
const arrayOfPromises = [
    ()=> {
        return new Promise((resolve, reject)=> {
            setTimeout(function () {
                testString += '1';
                resolve();
            }, 10);
        });
    },
    ()=> {
        return new Promise((resolve, reject)=> {
            setTimeout(function () {
                testString += '2';
                resolve();
            }, 200);
        });

    },
    ()=> {
        return new Promise((resolve, reject)=> {
            testString += '3';
            resolve(testString);
        });

    }];

Now we need to execute these promises, in order:

function processArrayOfPromises(array) {
    var index = 0;

    return new Promise(function(resolve, reject) {

        function next() {
            if (index < array.length) {
                array[index++]().then(next, reject);
            } else {
                resolve();
            }
        }
        next();
    });
}

processArrayOfPromises(arrayOfPromises); // testString = '123'

Note that if we just defined an array of promises (rather than an array of functions that return a promise) like below, they'd execute as soon as they were defined and testString would be '312',

let testString = '';
// don't define the array like this because the promises will start executing immediately
const arrayOfPromises = [
    new Promise((resolve, reject)=> {
        setTimeout(function () {
            testString += '1';
            resolve();
        }, 10);
    }),
    new Promise((resolve, reject)=> {
        setTimeout(function () {
            testString += '2';
            resolve();
        }, 200);
    }),
    new Promise((resolve, reject)=> {
        testString += '3';
        resolve(testString);
    })
];

npm package

You can use this module in your code by first installing the package:

npm install synchronous-octo-broccoli

and then importing it like so:

import sob from 'synchronous-octo-broccoli';


const promises = [...];
sob(promises).then((d)=>{
    console.log('All done');
});
Please enable JavaScript to view the comments powered by Disqus.