Last active
June 23, 2020 15:08
-
-
Save park-brian/793a7193307c1a6308a794891756e601 to your computer and use it in GitHub Desktop.
promise-utils
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sometimes, we need a plain es5 function to chain execution of promises (eg: when | |
* targeting older browsers using polyfills, while eschewing a build step). This function | |
* takes an array of promises or functions which return promises, and applies the supplied | |
* callback function against each promise sequentially, waiting for resolution before | |
* executing/resolving the next promise. | |
* | |
* Promises always resolve in their order of appearance. However, this function only | |
* defers execution of promises if functions which return promises are provided (eg: | |
* using .bind to create bound functions). | |
* | |
* If the supplied callback function also returns a promise, then execution/resolution | |
* of the next promise will be deferred until the callback resolves. | |
* | |
* Returns a promise which resolves once the chain resolves. | |
* | |
* @example | |
* function addOne(num) { | |
* return new Promise(function(resolve, reject) { | |
* setTimeout(function() { | |
* resolve(num + 1); | |
* }, num * 1000); | |
* }) | |
* } | |
* | |
* // bind functions to defer execution of promises until called | |
* var promises = [ | |
* addOne.bind(null, 1), | |
* addOne.bind(null, 2), | |
* addOne.bind(null, 3) | |
* ]; | |
* | |
* // forEachPromise resolves once the last promise/callback has finished | |
* forEachPromise(promises, function(result, i) { | |
* console.log('result', result, 'index', i); | |
* return new Promise(function(resolve, reject) { | |
* console.log('adding 100ms delay before continuing'); | |
* setTimeout(function() { | |
* resolve(null); | |
* }, 100); | |
* }); | |
* }).then(function() { | |
* console.log('Finished execution'); | |
* }); | |
* | |
* @param promises {Promise<any>[] | (() => Promise<any>)[]} An array of promises, | |
* functions which return promises, or promises that return promises | |
* @param callback {(resolvedValue: any, index: number, promiseArray: (Promise<any>[] | (() => Promise<any>)[]), resolvedPromise: Promise) => (Promise | any | void)} | |
* A callback to be applied to each promise's resolved value | |
* @returns {Promise} A promise which resolves once the last promise in the chain resolves | |
*/ | |
function forEachPromise(promises, callback) { | |
var promiseChain; | |
promises.forEach(function(promise, i) { | |
// returns a promise which resolves after the callback finishes | |
function promiseCallback() { | |
var resolvedPromise = Promise.resolve( | |
promise instanceof Function ? promise() : promise | |
); | |
return resolvedPromise.then(function (result) { | |
return callback(result, i, promises, resolvedPromise); | |
}); | |
} | |
// initializes the inital promise, then chains promises | |
promiseChain = i === 0 | |
? promiseCallback() | |
: promiseChain.then(promiseCallback); | |
}); | |
return promiseChain; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Takes an array of promises, functions which return promises and reduces the resolved | |
* values sequentially against the supplied callback function. | |
* | |
* Promises always resolve in their order of appearance. However, this function only | |
* defers execution of promises if functions which return promises are provided (eg: | |
* using .bind to create bound functions). | |
* | |
* If the supplied callback function also returns a promise, then execution/resolution | |
* of the next promise will be deferred until the callback resolves. | |
* | |
* Returns a promise which resolves with the reduced value once the chain resolves. | |
* | |
* @param promises {Promise<any>[] | (() => Promise<any>)[]} An array of promises, | |
* functions which return promises, or promises that return promises | |
* @param callback {(accumulator: any, resolvedValue: any, index: number, promiseArray: (Promise<any>[] | (() => Promise<any>)[]), resolvedPromise: Promise<any>) => (Promise<any> | any)} | |
* A callback to be applied to each promise's resolved value | |
* @returns {Promise} A promise which resolves once the last promise in the chain resolves | |
*/ | |
function reducePromise(promises, callback, initialValue) { | |
var accumulator = initialValue; | |
var promiseChain; | |
promises.forEach(function(promise, i) { | |
// returns a promise which resolves after the callback finishes | |
function promiseCallback() { | |
var resolvedPromise = Promise.resolve( | |
promise instanceof Function ? promise() : promise | |
); | |
return resolvedPromise.then(function (result) { | |
// if an initial value is not supplied, use the first promise's resolved value | |
if (i === 0 && accumulator === undefined) | |
accumulator = result; | |
return callback(accumulator, result, i, promises, resolvedPromise); | |
}).then(function(callbackResult) { | |
accumulator = callbackResult; | |
return accumulator; | |
}); | |
} | |
// initializes the inital promise, then chains promises | |
promiseChain = i === 0 | |
? promiseCallback() | |
: promiseChain.then(promiseCallback); | |
}); | |
return promiseChain; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment