edge-core-js
Version:
Edge account & wallet management library
95 lines (89 loc) • 2.22 kB
JavaScript
/**
* Waits for the first successful promise.
* If no promise succeeds, returns the last failure.
*/
export function anyPromise(promises) {
return new Promise((resolve, reject) => {
let failed = 0
for (const promise of promises) {
promise.then(resolve, error => {
if (++failed >= promises.length) reject(error)
})
}
})
}
/**
* If the promise doesn't resolve in the given time,
* reject it with the provided error, or a generic error if none is provided.
*/
export function timeout(
promise,
ms,
error = new Error(`Timeout of ${ms}ms exceeded`)
) {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => reject(error), ms)
promise.then(
ok => {
clearTimeout(timer)
resolve(ok)
},
error => {
clearTimeout(timer)
reject(error)
}
)
})
}
/**
* Waits for a collection of promises.
* Returns all the promises that manage to resolve within the timeout.
* If no promises mange to resolve within the timeout,
* returns the first promise that resolves.
* If all promises reject, rejects an array of errors.
*/
export function fuzzyTimeout(
promises,
timeoutMs
) {
return new Promise((resolve, reject) => {
let done = false
const results = []
const errors = []
// Set up the timer:
let timer = setTimeout(() => {
timer = undefined
if (results.length > 0) {
done = true
resolve({ results, errors })
}
}, timeoutMs)
function checkEnd() {
const allDone = results.length + errors.length === promises.length
if (allDone && timer != null) {
clearTimeout(timer)
}
if (allDone || timer == null) {
done = true
if (results.length > 0) resolve({ results, errors })
else reject(errors)
}
}
checkEnd() // Handle empty lists
// Attach to the promises:
for (const promise of promises) {
promise.then(
result => {
if (done) return
results.push(result)
checkEnd()
},
failure => {
if (done) return
errors.push(failure)
checkEnd()
}
)
}
})
}