Skip to content

Instantly share code, notes, and snippets.

@ducin
Last active April 21, 2017 17:54
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 ducin/ca918d24e660780eccaa60c8a3dc9363 to your computer and use it in GitHub Desktop.
Save ducin/ca918d24e660780eccaa60c8a3dc9363 to your computer and use it in GitHub Desktop.
resolvedSame - new promise aggregate

resolveSame - new promise aggregate

  • if all promises get rejected - aggregate gets rejected (with positional reasons)
  • if some promises get resolved, then:
    • if they all get resolved with the same value - aggregate gets resolved with theValue
    • otherwise (different resolved values) - aggregate gets rejected with first two different values
const resolvedSame = (promises, same = reference) => {
const rejections = [];
return new Promise((resolve, reject) => {
let set = false, theValue;
promises.reduce((aggr, p) => {
return aggr
.then(_ => p)
.then(v => {
if (!set) { // first resolved
set = true;
theValue = v;
} else { // another ones
if (!same(theValue, v)) reject(new Error(`Different elements: ${theValue}, ${v}`));
}
})
.catch(e => rejections.push(e))
}, Promise.resolve(null) /* reduce initial value */)
.then(_ => set ? resolve(theValue) : reject(rejections))
.catch(_ => set ? resolve(theValue) : reject(rejections));
})
}
// disposable promise factories
const resolveDelay = (value, delay) =>
new Promise((resolve, reject) => {
setTimeout(() => resolve(value), delay);
});
const rejectDelay = (reason, delay) =>
new Promise((resolve, reject) => {
setTimeout(() => reject(reason), delay);
});
// scenario 1 - expect to reject (all rejected)
resolvedSame([
rejectDelay('e', 500),
rejectDelay('e', 300),
rejectDelay('e', 1000)
])
.then(console.info)
.catch(console.warn)
// scenario 2 - expect to reject (different resolved values)
resolvedSame([
rejectDelay('e', 500),
resolveDelay(1, 300),
resolveDelay(2, 1000)
])
.then(console.info)
.catch(console.warn)
// scenario 3 - expect to resolve (identical resolved values, only one resolved)
resolvedSame([
rejectDelay('e', 500),
rejectDelay('e', 300),
resolveDelay(2, 1000)
])
.then(console.info)
.catch(console.warn)
// scenario 4 - expect to resolve (identical resolved values, more than one resolved)
resolvedSame([
resolveDelay(2, 500),
resolveDelay(2, 300),
resolveDelay(2, 1000)
])
.then(console.info)
.catch(console.warn)
// scenario 5 - expect to reject (checking for race conditions)
resolvedSame([
resolveDelay(2, 4000),
resolveDelay(1, 300),
resolveDelay(1, 1000),
])
.then(console.info)
.catch(console.warn)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment