-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.ts
74 lines (62 loc) · 2.47 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// deno-lint-ignore-file no-explicit-any
import { ResolvablePromise } from 'https://ghuc.cc/worker-tools/resolvable-promise/index.ts';
// const queueMicrotask = typeof globalThis.queueMicrotask === "function"
// ? globalThis.queueMicrotask
// : (callback: VoidFunction) => Promise.resolve().then(callback).catch(e => setTimeout(() => { throw e }));
export class ExtendablePromise<T = unknown> implements Promise<PromiseSettledResult<T>[]> {
#values: PromiseSettledResult<T>[] = [];
#promise: ResolvablePromise<PromiseSettledResult<T>[]>;
#numAdded = 0;
#numSettled = 0;
constructor(f?: T | PromiseLike<T>) {
// super(_ => _(void 0 as any));
this.#promise = new ResolvablePromise();
this.waitUntil(f);
// queueMicrotask(() => {
// if (this.#numAdded === 0) {
// this.#promise.resolve([]);
// }
// });
}
#fulfill(i: number, value: T) {
this.#values[i] = { status: 'fulfilled', value };
if (++this.#numSettled === this.#numAdded) {
this.#promise.resolve(this.#values);
}
}
#reject(i: number, reason: any) {
this.#values[i] = { status: 'rejected', reason };
if (++this.#numSettled === this.#numAdded) {
this.#promise.resolve(this.#values);
}
}
waitUntil(f?: T | PromiseLike<T>) {
if (f != null) {
const i = this.#numAdded;
Promise.resolve(f)
.then(v => this.#fulfill(i, v), r => this.#reject(i, r))
this.#numAdded++;
}
}
/** @deprecated Name of this property might change */
get settled() { return this.#promise.settled }
then<TResult1 = PromiseSettledResult<T>[], TResult2 = never>(onfulfilled?: ((value: PromiseSettledResult<T>[]) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2> {
return this.#promise.then(onfulfilled, onrejected);
}
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null): Promise<PromiseSettledResult<T>[] | TResult> {
return this.#promise.catch(onrejected);
}
finally(onfinally?: (() => void) | null): Promise<PromiseSettledResult<T>[]> {
return this.#promise.finally(onfinally);
}
readonly [Symbol.toStringTag] = 'ExtendablePromise'
}
export interface PromiseFulfilledResult<T> {
status: "fulfilled";
value: T;
}
export interface PromiseRejectedResult {
status: "rejected";
reason: any;
}
export type PromiseSettledResult<T> = PromiseFulfilledResult<T> | PromiseRejectedResult;