silphius/app/util/promise.js
2024-07-22 01:31:52 -05:00

68 lines
1.6 KiB
JavaScript

export const all = Promise.all.bind(Promise);
export const allSettled = Promise.allSettled.bind(Promise);
export const any = Promise.any.bind(Promise);
export const race = Promise.race.bind(Promise);
export const reject = Promise.reject.bind(Promise);
export const resolve = Promise.resolve.bind(Promise);
export function withResolvers() {
let resolve, reject, promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return {promise, reject, resolve};
}
export class Ticker extends Promise {
constructor(executor, ticker) {
let _reject;
let _resolve;
super((resolve, reject) => {
_reject = reject;
_resolve = resolve;
if (executor) {
executor(resolve, reject);
}
});
this.reject = _reject;
this.resolve = _resolve;
this.ticker = ticker;
}
static all(promises) {
const tickers = [];
for (let i = 0; i < promises.length; i++) {
const promise = promises[i];
if (promise instanceof Ticker) {
tickers.push(promise);
// After resolution, stop ticking the promise.
promise.then(() => {
tickers.splice(tickers.indexOf(promise), 1);
});
}
}
/* v8 ignore next 3 */
if (0 === tickers.length) {
return super.all(promises);
}
return new Ticker(
(resolve, reject) => {
super.all(promises)
.then(resolve)
/* v8 ignore next */
.catch(reject);
},
(elapsed) => {
for (let i = 0; i < tickers.length; i++) {
tickers[i].tick(elapsed);
}
},
);
}
tick(elapsed) {
this.ticker(elapsed, this.resolve, this.reject);
}
}