1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-27 16:10:57 -05:00
denoland-deno/ext/node/polyfills/_util/async.ts

58 lines
1.8 KiB
TypeScript

// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// This module is vendored from std/async/deferred.ts and std/async/delay.ts
// (with some modifications)
// TODO(petamoriken): enable prefer-primordials for node polyfills
// deno-lint-ignore-file prefer-primordials
export interface Deferred<T> extends Promise<T> {
readonly state: "pending" | "fulfilled" | "rejected";
resolve(value?: T | PromiseLike<T>): void;
// deno-lint-ignore no-explicit-any
reject(reason?: any): void;
}
/** Creates a Promise with the `reject` and `resolve` functions */
export function deferred<T>(): Deferred<T> {
let methods;
let state = "pending";
const promise = new Promise<T>((resolve, reject) => {
methods = {
async resolve(value: T | PromiseLike<T>) {
await value;
state = "fulfilled";
resolve(value);
},
// deno-lint-ignore no-explicit-any
reject(reason?: any) {
state = "rejected";
reject(reason);
},
};
});
Object.defineProperty(promise, "state", { get: () => state });
return Object.assign(promise, methods) as Deferred<T>;
}
/** Resolve a Promise after a given amount of milliseconds. */
export function delay(
ms: number,
options: { signal?: AbortSignal } = {},
): Promise<void> {
const { signal } = options;
if (signal?.aborted) {
return Promise.reject(new DOMException("Delay was aborted.", "AbortError"));
}
return new Promise((resolve, reject) => {
const abort = () => {
clearTimeout(i);
reject(new DOMException("Delay was aborted.", "AbortError"));
};
const done = () => {
signal?.removeEventListener("abort", abort);
resolve();
};
const i = setTimeout(done, ms);
signal?.addEventListener("abort", abort, { once: true });
});
}