mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 10:15:07 +08:00
Add an experimental `net/promises` namespace, accessible via
`require('node:net/promises')` or `net.promises`, mirroring the existing
`fs/promises` and `dns/promises` modules.
It provides promise-based variants of net's one-shot lifecycle
operations:
- `connect()` returns a promise that fulfills with a connected Socket
once the 'connect' event fires, and rejects on connection failure or
when an optional AbortSignal is aborted, destroying the socket.
- `listen()` creates a server, begins listening, and returns a promise
that fulfills with the listening Server once the 'listening' event
fires. It rejects if the server fails to bind or an optional
AbortSignal is aborted, closing the server.
The functions are named for the actions they await, forming a parallel
`connect()`/`listen()` pair. This is intentionally not the callback
API's factory taxonomy: there `createConnection()` is canonical because
it both creates a socket and initiates connecting, whereas
`createServer()` is a pure factory that does not listen. A
`createConnection`/`createServer` pairing would be inconsistent here
because `createServer` has no completion to await, so no
`createConnection` alias is provided.
Refs: https://github.com/nodejs/node/issues/21482
Assisted-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Ethan Arrowood <ethan@arrowood.dev>
PR-URL: https://github.com/nodejs/node/pull/63965
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
63 lines
1.9 KiB
JavaScript
63 lines
1.9 KiB
JavaScript
'use strict';
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const net = require('net');
|
|
const { once } = require('events');
|
|
const { connect } = require('net/promises');
|
|
|
|
(async () => {
|
|
// Resolves with a connected socket and round-trips data.
|
|
{
|
|
const server = net.createServer((socket) => {
|
|
socket.end('hello');
|
|
}).listen(0);
|
|
await once(server, 'listening');
|
|
const socket = await connect({ port: server.address().port });
|
|
assert.strictEqual(socket.connecting, false);
|
|
const chunks = [];
|
|
for await (const chunk of socket) {
|
|
chunks.push(chunk);
|
|
}
|
|
assert.strictEqual(Buffer.concat(chunks).toString(), 'hello');
|
|
server.close();
|
|
}
|
|
|
|
// net.promises is the same object as require('net/promises').
|
|
assert.strictEqual(net.promises, require('net/promises'));
|
|
|
|
// Rejects when the connection is refused.
|
|
{
|
|
const server = net.createServer().listen(0);
|
|
await once(server, 'listening');
|
|
const { port } = server.address();
|
|
server.close();
|
|
await once(server, 'close');
|
|
await assert.rejects(connect({ port }), { code: 'ECONNREFUSED' });
|
|
}
|
|
|
|
// A pre-aborted signal rejects with an AbortError.
|
|
{
|
|
await assert.rejects(
|
|
connect({ port: 0, signal: AbortSignal.abort() }),
|
|
{ name: 'AbortError' });
|
|
}
|
|
|
|
// Aborting while connecting rejects with an AbortError.
|
|
{
|
|
const server = net.createServer().listen(0);
|
|
await once(server, 'listening');
|
|
const controller = new AbortController();
|
|
const promise = connect({ port: server.address().port, signal: controller.signal });
|
|
controller.abort();
|
|
await assert.rejects(promise, { name: 'AbortError' });
|
|
server.close();
|
|
}
|
|
|
|
// An invalid signal throws.
|
|
{
|
|
await assert.rejects(
|
|
connect({ port: 0, signal: 'INVALID_SIGNAL' }),
|
|
{ code: 'ERR_INVALID_ARG_TYPE' });
|
|
}
|
|
})().then(common.mustCall());
|