pSettle() returns an object for an object.

This commit is contained in:
Julien Fontanet 2015-11-20 11:42:49 +01:00
parent 9fe3ef430f
commit 04239c57fe
2 changed files with 76 additions and 61 deletions

View File

@ -4,7 +4,6 @@ import has from 'lodash.has'
import humanFormat from 'human-format' import humanFormat from 'human-format'
import isArray from 'lodash.isarray' import isArray from 'lodash.isarray'
import isString from 'lodash.isstring' import isString from 'lodash.isstring'
import mapToArray from 'lodash.map'
import multiKeyHashInt from 'multikey-hash' import multiKeyHashInt from 'multikey-hash'
import xml2js from 'xml2js' import xml2js from 'xml2js'
import {promisify} from 'bluebird' import {promisify} from 'bluebird'
@ -107,31 +106,45 @@ export function pFinally (cb) {
) )
} }
// Given an array which contains promises return a promise that is // Given a collection (array or object) which contains promises,
// fulfilled when all the items in the array are either fulfilled or // return a promise that is fulfilled when all the items in the
// rejected. // collection are either fulfilled or rejected.
//
// This promise will be fulfilled with a collection (of the same type,
// array or object) containing promise inspections.
export function pSettle (promises) { export function pSettle (promises) {
return Promise.all(mapToArray( let mainPromise = Promise.resolve()
promises,
promise => Promise.resolve(promise).then( const results = 'length' in promises
value => ({ ? new Array(promises.length)
isFulfilled: () => true, : {}
isRejected: () => false,
value: () => value, forEach(promises, (promise, key) => {
reason: () => { mainPromise = mainPromise.then(() => promise).then(
throw new Error('no reason, the promise has been fulfilled') value => {
results[key] = {
isFulfilled: () => true,
isRejected: () => false,
value: () => value,
reason: () => {
throw new Error('no reason, the promise has been fulfilled')
}
} }
}), },
reason => ({ reason => {
isFulfilled: () => false, results[key] = {
isRejected: () => true, isFulfilled: () => false,
value: () => { isRejected: () => true,
throw new Error('no value, the promise has been rejected') value: () => {
}, throw new Error('no value, the promise has been rejected')
reason: () => reason },
}) reason: () => reason
}
}
) )
)) })
return mainPromise.then(() => results)
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -122,38 +122,6 @@ describe('generateToken()', () => {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
describe('pSettle()', () => {
it('makes an array of PromiseInspection', async () => {
const [
status1,
status2,
status3
] = await pSettle([
Promise.resolve(42),
Math.PI,
Promise.reject('fatality')
])
expect(status1.isRejected()).to.equal(false)
expect(status2.isRejected()).to.equal(false)
expect(status3.isRejected()).to.equal(true)
expect(status1.isFulfilled()).to.equal(true)
expect(status2.isFulfilled()).to.equal(true)
expect(status3.isFulfilled()).to.equal(false)
expect(status1.value()).to.equal(42)
expect(status2.value()).to.equal(Math.PI)
expect(::status3.value).to.throw()
expect(::status1.reason).to.throw()
expect(::status2.reason).to.throw()
expect(status3.reason()).to.equal('fatality')
})
})
// -------------------------------------------------------------------
describe('parseSize()', function () { describe('parseSize()', function () {
it('parses a human size', function () { it('parses a human size', function () {
expect(parseSize('1G')).to.equal(1e9) expect(parseSize('1G')).to.equal(1e9)
@ -207,25 +175,59 @@ describe('pFinally()', () => {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
describe('pSettle()', () => { describe('pSettle()', () => {
it('makes an array of PromiseInspection', async () => { it('works with arrays', async () => {
const [ const [
status1, status1,
status2 status2,
status3
] = await pSettle([ ] = await pSettle([
Promise.resolve(42), Promise.resolve(42),
Math.PI,
Promise.reject('fatality') Promise.reject('fatality')
]) ])
expect(status1.isRejected()).to.equal(false) expect(status1.isRejected()).to.equal(false)
expect(status2.isRejected()).to.equal(true) expect(status2.isRejected()).to.equal(false)
expect(status3.isRejected()).to.equal(true)
expect(status1.isFulfilled()).to.equal(true) expect(status1.isFulfilled()).to.equal(true)
expect(status2.isFulfilled()).to.equal(false) expect(status2.isFulfilled()).to.equal(true)
expect(status3.isFulfilled()).to.equal(false)
expect(status1.value()).to.equal(42) expect(status1.value()).to.equal(42)
expect(::status2.value).to.throw() expect(status2.value()).to.equal(Math.PI)
expect(::status3.value).to.throw()
expect(::status1.reason).to.throw() expect(::status1.reason).to.throw()
expect(status2.reason()).to.equal('fatality') expect(::status2.reason).to.throw()
expect(status3.reason()).to.equal('fatality')
})
it('works with objects', async () => {
const {
a: status1,
b: status2,
c: status3
} = await pSettle({
a: Promise.resolve(42),
b: Math.PI,
c: Promise.reject('fatality')
})
expect(status1.isRejected()).to.equal(false)
expect(status2.isRejected()).to.equal(false)
expect(status3.isRejected()).to.equal(true)
expect(status1.isFulfilled()).to.equal(true)
expect(status2.isFulfilled()).to.equal(true)
expect(status3.isFulfilled()).to.equal(false)
expect(status1.value()).to.equal(42)
expect(status2.value()).to.equal(Math.PI)
expect(::status3.value).to.throw()
expect(::status1.reason).to.throw()
expect(::status2.reason).to.throw()
expect(status3.reason()).to.equal('fatality')
}) })
}) })