diff --git a/src/utils.js b/src/utils.js index e53a36f06..e3f6da63d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -106,6 +106,32 @@ export function pFinally (cb) { ) } +// Given an array which contains promises return a promise that is +// fulfilled when all the items in the array are either fulfilled or +// rejected. +export function pSettle (promises) { + const statuses = promises.map(promise => promise.then( + value => ({ + isFulfilled: () => true, + isRejected: () => false, + value: () => value, + reason: () => { + throw new Error('no reason, the promise has been fulfilled') + } + }), + reason => ({ + isFulfilled: () => false, + isRejected: () => true, + value: () => { + throw new Error('no value, the promise has been rejected') + }, + reason: () => reason + }) + )) + + return Promise.all(statuses) +} + // ------------------------------------------------------------------- export { diff --git a/src/utils.spec.js b/src/utils.spec.js index 13cd8ee40..369cd8ee2 100644 --- a/src/utils.spec.js +++ b/src/utils.spec.js @@ -13,7 +13,8 @@ import { formatXml, generateToken, parseSize, - pFinally + pFinally, + pSettle } from './utils' // =================================================================== @@ -170,3 +171,29 @@ describe('pFinally()', () => { expect(spy.callCount).to.equal(1) }) }) + +// ------------------------------------------------------------------- + +describe('pSettle()', () => { + it('makes an array of PromiseInspection', async () => { + const [ + status1, + status2 + ] = await pSettle([ + Promise.resolve(42), + Promise.reject('fatality') + ]) + + expect(status1.isRejected()).to.equal(false) + expect(status2.isRejected()).to.equal(true) + + expect(status1.isFulfilled()).to.equal(true) + expect(status2.isFulfilled()).to.equal(false) + + expect(status1.value()).to.equal(42) + expect(::status2.value).to.throw() + + expect(::status1.reason).to.throw() + expect(status2.reason()).to.equal('fatality') + }) +})