Skip to content

Instantly share code, notes, and snippets.

@westc
Last active April 6, 2020 12:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westc/c5a579c823dae3f4162f4cd8450ea9c3 to your computer and use it in GitHub Desktop.
Save westc/c5a579c823dae3f4162f4cd8450ea9c3 to your computer and use it in GitHub Desktop.
Gets a single promise for multiple function returning their own promises. Allows for sequential promise execution and asynchronous promise execution.
/**
* Gets a single promise for multiple function returning their own promises.
* Allows for sequential promise execution and asynchronous promise execution.
* @param {Array<(function():Promise|Array<function():Promise>)>} promiseMakers
* An array which can contain functions and arrays of functions. Each
* top-level function when called must return a promise that will be waited
* for sequentially. In the case of an item in the top-level array being an
* array of functions, each of thise functions must return promises but all of
* these promises will be executed asynchronously. Each item in this
* top-level array will wait for the previous item. If a returned promise
* fails the promise returned from this function will immediately fail.
* @returns {Promise}
* One promise representing all of the underlying promises returned by the
* functions in the promiseMakers array.
*/
function getMultiPromise(promiseMakers) {
return promiseMakers.reduce(function(prevPromise, promiseMaker) {
return prevPromise.then(function() {
return Array.isArray(promiseMaker)
? Promise.all(promiseMaker.map(function(subPromiseMaker) {
return subPromiseMaker()
}))
: promiseMaker();
});
}, Promise.resolve());
}
// HIDE \\
console.load('local://getMultiPromise.js');
// HIDE \\
console.load('local://~example~test~functions.js');
// \\
getMultiPromise([
succeedAfter(0.5),
succeedAfter(0.4),
[
succeedAfter(1),
succeedAfter(1),
succeedAfter(1.3),
succeedAfter(1.3),
succeedAfter(1)
],
failAfter(0.2),
succeedAfter(0.1)
]).then(function(result) {
console.log('DONE:', result);
})
.catch(function(result) {
console.log('DONE (catch):', result);
});
// HIDE \\
console.load('local://getMultiPromise.js');
// HIDE \\
console.load('local://~example~test~functions.js');
// \\
getMultiPromise([
succeedAfter(0.5),
succeedAfter(0.4),
[
succeedAfter(1),
failAfter(1),
succeedAfter(1.3),
succeedAfter(1.3),
succeedAfter(1)
],
succeedAfter(0.2),
succeedAfter(0.1)
]).then(function(result) {
console.log('DONE:', result);
})
.catch(function(result) {
console.log('DONE (catch):', result);
});
// HIDE \\
console.load('local://getMultiPromise.js');
// HIDE \\
console.load('local://~example~test~functions.js');
// \\
getMultiPromise([
succeedAfter(0.5),
succeedAfter(0.4),
[
succeedAfter(1),
succeedAfter(1),
succeedAfter(1),
succeedAfter(1),
succeedAfter(1)
],
succeedAfter(0.2),
succeedAfter(0.1)
]).then(function(result) {
console.log('DONE:', result);
})
.catch(function(result) {
console.log('DONE (catch):', result);
});
var getNextIter = (function(iter) {
return function() {
return ++iter;
};
})(0);
function succeedAfter(secs) {
return function() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
var msg = getNextIter() + ': Success after ' + secs + ' second(s)';
console.log(msg);
resolve(msg);
}, secs * 1e3);
});
}
}
function failAfter(secs) {
return function() {
return new Promise(function(resolve, reject) {
setTimeout(() => {
var msg = getNextIter() + ': Failure after ' + secs + ' second(s)';
console.log(msg);
reject(msg);
}, secs * 1e3);
});
}
}