summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorAsher Gomez <ashersaupingomez@gmail.com>2023-11-22 22:11:20 +1100
committerGitHub <noreply@github.com>2023-11-22 12:11:20 +0100
commit616354e76cba0be8af20a0ffefeacfcf6101bafc (patch)
treec832c81dd93498e196840c8d59c0a4ab76396d07 /ext
parent0ffcb46e0f60110c07e21151db6066f5a1b5f710 (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.ts31
-rw-r--r--ext/node/polyfills/http.ts11
-rw-r--r--ext/node/polyfills/http2.ts25
-rw-r--r--ext/node/polyfills/internal/child_process.ts13
-rw-r--r--ext/node/polyfills/testing.ts25
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,
};