diff options
author | Asher Gomez <ashersaupingomez@gmail.com> | 2023-11-22 22:11:20 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-22 12:11:20 +0100 |
commit | 616354e76cba0be8af20a0ffefeacfcf6101bafc (patch) | |
tree | c832c81dd93498e196840c8d59c0a4ab76396d07 /ext | |
parent | 0ffcb46e0f60110c07e21151db6066f5a1b5f710 (diff) |
refactor: replace `deferred()` from `std/async` with `Promise.withResolvers()` (#21234)
Closes #21041
---------
Signed-off-by: Asher Gomez <ashersaupingomez@gmail.com>
Diffstat (limited to 'ext')
-rw-r--r-- | ext/node/polyfills/_util/async.ts | 31 | ||||
-rw-r--r-- | ext/node/polyfills/http.ts | 11 | ||||
-rw-r--r-- | ext/node/polyfills/http2.ts | 25 | ||||
-rw-r--r-- | ext/node/polyfills/internal/child_process.ts | 13 | ||||
-rw-r--r-- | ext/node/polyfills/testing.ts | 25 |
5 files changed, 28 insertions, 77 deletions
diff --git a/ext/node/polyfills/_util/async.ts b/ext/node/polyfills/_util/async.ts index a05b670e8..5eeda2a37 100644 --- a/ext/node/polyfills/_util/async.ts +++ b/ext/node/polyfills/_util/async.ts @@ -1,39 +1,10 @@ // 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 +// This module is vendored from 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, diff --git a/ext/node/polyfills/http.ts b/ext/node/polyfills/http.ts index 4ad502760..475d691cc 100644 --- a/ext/node/polyfills/http.ts +++ b/ext/node/polyfills/http.ts @@ -7,7 +7,6 @@ const core = globalThis.__bootstrap.core; import { TextEncoder } from "ext:deno_web/08_text_encoding.js"; -import { type Deferred, deferred } from "ext:deno_node/_util/async.ts"; import { setTimeout } from "ext:deno_web/02_timers.js"; import { _normalizeArgs, @@ -1556,7 +1555,7 @@ export class ServerImpl extends EventEmitter { #server: Deno.Server; #unref = false; #ac?: AbortController; - #servePromise: Deferred<void>; + #serveDeferred: ReturnType<typeof Promise.withResolvers<void>>; listening = false; constructor(opts, requestListener?: ServerHandler) { @@ -1573,8 +1572,8 @@ export class ServerImpl extends EventEmitter { this._opts = opts; - this.#servePromise = deferred(); - this.#servePromise.then(() => this.emit("close")); + this.#serveDeferred = Promise.withResolvers<void>(); + this.#serveDeferred.promise.then(() => this.emit("close")); if (requestListener !== undefined) { this.on("request", requestListener); } @@ -1660,7 +1659,7 @@ export class ServerImpl extends EventEmitter { if (this.#unref) { this.#server.unref(); } - this.#server.finished.then(() => this.#servePromise!.resolve()); + this.#server.finished.then(() => this.#serveDeferred!.resolve()); } setTimeout() { @@ -1700,7 +1699,7 @@ export class ServerImpl extends EventEmitter { this.#ac.abort(); this.#ac = undefined; } else { - this.#servePromise!.resolve(); + this.#serveDeferred!.resolve(); } this.#server = undefined; diff --git a/ext/node/polyfills/http2.ts b/ext/node/polyfills/http2.ts index 50d85f694..afd9a22bc 100644 --- a/ext/node/polyfills/http2.ts +++ b/ext/node/polyfills/http2.ts @@ -20,7 +20,6 @@ import { import { FileHandle } from "node:fs/promises"; import { kStreamBaseField } from "ext:deno_node/internal_binding/stream_wrap.ts"; import { addTrailers, serveHttpOnConnection } from "ext:deno_http/00_serve.js"; -import { type Deferred, deferred } from "ext:deno_node/_util/async.ts"; import { nextTick } from "ext:deno_node/_next_tick.ts"; import { TextEncoder } from "ext:deno_web/08_text_encoding.js"; import { Duplex } from "node:stream"; @@ -552,9 +551,9 @@ function getAuthority(headers) { export class Http2Stream extends EventEmitter { #session: Http2Session; - #headers: Deferred<Http2Headers>; - #controllerPromise: Deferred<ReadableStreamDefaultController<Uint8Array>>; - #readerPromise: Deferred<ReadableStream<Uint8Array>>; + #headers: Promise<Http2Headers>; + #controllerPromise: Promise<ReadableStreamDefaultController<Uint8Array>>; + #readerPromise: Promise<ReadableStream<Uint8Array>>; #closed: boolean; _response: Response; @@ -1260,7 +1259,7 @@ function callTimeout() { } export class ServerHttp2Stream extends Http2Stream { - _promise: Deferred<Response>; + _deferred: ReturnType<typeof Promise.withResolvers<Response>>; #body: ReadableStream<Uint8Array>; #waitForTrailers: boolean; #headersSent: boolean; @@ -1273,7 +1272,7 @@ export class ServerHttp2Stream extends Http2Stream { body: ReadableStream<Uint8Array>, ) { super(session, headers, controllerPromise, Promise.resolve(reader)); - this._promise = new deferred(); + this._deferred = Promise.withResolvers<Response>(); this.#body = body; } @@ -1319,10 +1318,10 @@ export class ServerHttp2Stream extends Http2Stream { } } if (options?.endStream) { - this._promise.resolve(this._response = new Response("", response)); + this._deferred.resolve(this._response = new Response("", response)); } else { this.#waitForTrailers = options?.waitForTrailers; - this._promise.resolve( + this._deferred.resolve( this._response = new Response(this.#body, response), ); } @@ -1368,12 +1367,12 @@ export class Http2Server extends Server { this.#abortController.signal, async (req: Request) => { try { - const controllerPromise: Deferred< + const controllerDeferred = Promise.withResolvers< ReadableStreamDefaultController<Uint8Array> - > = deferred(); + >(); const body = new ReadableStream({ start(controller) { - controllerPromise.resolve(controller); + controllerDeferred.resolve(controller); }, }); const headers: Http2Headers = {}; @@ -1385,13 +1384,13 @@ export class Http2Server extends Server { const stream = new ServerHttp2Stream( session, Promise.resolve(headers), - controllerPromise, + controllerDeferred.promise, req.body, body, ); session.emit("stream", stream, headers); this.emit("stream", stream, headers); - return await stream._promise; + return await stream._deferred.promise; } catch (e) { console.log(">>> Error in serveHttpOnConnection", e); } diff --git a/ext/node/polyfills/internal/child_process.ts b/ext/node/polyfills/internal/child_process.ts index 7d707758e..1c9aced19 100644 --- a/ext/node/polyfills/internal/child_process.ts +++ b/ext/node/polyfills/internal/child_process.ts @@ -11,7 +11,6 @@ import { EventEmitter } from "node:events"; import { os } from "ext:deno_node/internal_binding/constants.ts"; import { notImplemented, warnNotImplemented } from "ext:deno_node/_utils.ts"; import { Readable, Stream, Writable } from "node:stream"; -import { deferred } from "ext:deno_node/_util/async.ts"; import { isWindows } from "ext:deno_node/_util/os.ts"; import { nextTick } from "ext:deno_node/_next_tick.ts"; import { @@ -151,7 +150,7 @@ export class ChildProcess extends EventEmitter { ]; #process!: Deno.ChildProcess; - #spawned = deferred<void>(); + #spawned = Promise.withResolvers<void>(); constructor( command: string, @@ -253,7 +252,7 @@ export class ChildProcess extends EventEmitter { (async () => { const status = await this.#process.status; this.exitCode = status.code; - this.#spawned.then(async () => { + this.#spawned.promise.then(async () => { const exitCode = this.signalCode == null ? this.exitCode : null; const signalCode = this.signalCode == null ? null : this.signalCode; // The 'exit' and 'close' events must be emitted after the 'spawn' event. @@ -688,22 +687,22 @@ function waitForReadableToClose(readable: Readable) { } function waitForStreamToClose(stream: Stream) { - const promise = deferred<void>(); + const deferred = Promise.withResolvers<void>(); const cleanup = () => { stream.removeListener("close", onClose); stream.removeListener("error", onError); }; const onClose = () => { cleanup(); - promise.resolve(); + deferred.resolve(); }; const onError = (err: Error) => { cleanup(); - promise.reject(err); + deferred.reject(err); }; stream.once("close", onClose); stream.once("error", onError); - return promise; + return deferred.promise; } /** diff --git a/ext/node/polyfills/testing.ts b/ext/node/polyfills/testing.ts index 192a0cc71..83e8f6f0b 100644 --- a/ext/node/polyfills/testing.ts +++ b/ext/node/polyfills/testing.ts @@ -5,23 +5,6 @@ import { notImplemented, warnNotImplemented } from "ext:deno_node/_utils.ts"; -export function deferred() { - let methods; - const promise = new Promise((resolve, reject) => { - methods = { - async resolve(value) { - await value; - resolve(value); - }, - // deno-lint-ignore no-explicit-any - reject(reason?: any) { - reject(reason); - }, - }; - }); - return Object.assign(promise, methods); -} - export function run() { notImplemented("test.run"); } @@ -124,13 +107,13 @@ function prepareOptions(name, options, fn, overrides) { return { fn, options: finalOptions, name }; } -function wrapTestFn(fn, promise) { +function wrapTestFn(fn, resolve) { return async function (t) { const nodeTestContext = new NodeTestContext(t); try { await fn(nodeTestContext); } finally { - promise.resolve(undefined); + resolve(); } }; } @@ -138,11 +121,11 @@ function wrapTestFn(fn, promise) { function prepareDenoTest(name, options, fn, overrides) { const prepared = prepareOptions(name, options, fn, overrides); - const promise = deferred(); + const { promise, resolve } = Promise.withResolvers(); const denoTestOptions = { name: prepared.name, - fn: wrapTestFn(prepared.fn, promise), + fn: wrapTestFn(prepared.fn, resolve), only: prepared.options.only, ignore: prepared.options.todo || prepared.options.skip, }; |