Skip to content

Instantly share code, notes, and snippets.

@xavierlepretre
Last active April 25, 2023 16:03
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xavierlepretre/0e24b1dc300e5aaea20c87e3d3039d29 to your computer and use it in GitHub Desktop.
Save xavierlepretre/0e24b1dc300e5aaea20c87e3d3039d29 to your computer and use it in GitHub Desktop.
Like `Promise.all()` but where all promises are started sequentially.
const Promise = require("bluebird");
/**
* @param {!Array.<function.Promise.<Any>>} promiseArray.
* @returns {!Promise.<Array.<Any>>} The results of the promises passed to the function.
*/
module.exports = function sequentialPromise(promiseArray) {
const result = promiseArray.reduce(
(reduced, promise, index) => {
reduced.results.push(undefined);
return {
chain: reduced.chain
.then(() => promise())
.then(result => reduced.results[ index ] = result),
results: reduced.results
};
},
{
chain: Promise.resolve(),
results: []
});
return result.chain.then(() => result.results);
};
@xavierlepretre
Copy link
Author

xavierlepretre commented Jun 22, 2017

Example:

sequentialPromise([
        () => Promise.resolve(1),
        () => Promise.resolve(2)
    ])
    .then(console.log);

Prints

[ 1, 2 ]

See full tests: https://github.com/b9lab/promise-extensions/blob/master/test/allSequential.js

@xavierlepretre
Copy link
Author

Because of the nature of Web3 and Javascript, it may happen that launching an aggressive Promise.all[ promise1, promise2 ] does not act as expected. What may have happened is that the non-atomic requestId++ that takes place before each RPC call was not, well, atomic.

This "Sequential Promises" gist makes sure that all promises of the array are executed in sequence. This incurs an obvious time penalty.

@xavierlepretre
Copy link
Author

xavierlepretre commented Jul 21, 2017

You can also use Web3 v1.0's BatchRequest: http://web3js.readthedocs.io/en/1.0/web3-eth.html#batchrequest

@whittlem
Copy link

I tried this out and getting this error message on line 13:
TypeError: promise is not a function

@xavierlepretre
Copy link
Author

You did:

sequentialPromise([
        Promise.resolve(1),
        Promise.resolve(2)
    ])

What you have to do is:

sequentialPromise([
        () => Promise.resolve(1),
        () => Promise.resolve(2)
    ])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment