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 isArray from 'lodash.isarray'
import isString from 'lodash.isstring'
import mapToArray from 'lodash.map'
import multiKeyHashInt from 'multikey-hash'
import xml2js from 'xml2js'
import {promisify} from 'bluebird'
@ -107,31 +106,45 @@ 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.
// Given a collection (array or object) which contains promises,
// return a promise that is fulfilled when all the items in the
// 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) {
return Promise.all(mapToArray(
promises,
promise => Promise.resolve(promise).then(
value => ({
isFulfilled: () => true,
isRejected: () => false,
value: () => value,
reason: () => {
throw new Error('no reason, the promise has been fulfilled')
let mainPromise = Promise.resolve()
const results = 'length' in promises
? new Array(promises.length)
: {}
forEach(promises, (promise, key) => {
mainPromise = mainPromise.then(() => promise).then(
value => {
results[key] = {
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
})
},
reason => {
results[key] = {
isFulfilled: () => false,
isRejected: () => true,
value: () => {
throw new Error('no value, the promise has been rejected')
},
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 () {
it('parses a human size', function () {
expect(parseSize('1G')).to.equal(1e9)
@ -207,25 +175,59 @@ describe('pFinally()', () => {
// -------------------------------------------------------------------
describe('pSettle()', () => {
it('makes an array of PromiseInspection', async () => {
it('works with arrays', async () => {
const [
status1,
status2
status2,
status3
] = await pSettle([
Promise.resolve(42),
Math.PI,
Promise.reject('fatality')
])
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(status2.isFulfilled()).to.equal(false)
expect(status2.isFulfilled()).to.equal(true)
expect(status3.isFulfilled()).to.equal(false)
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(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')
})
})