timers: support Symbol.dispose

PR-URL: https://github.com/nodejs/node/pull/48633
Reviewed-By: Zeyu "Alex" Yang <himself65@outlook.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
This commit is contained in:
Moshe Atlow 2023-07-05 16:39:38 +03:00 committed by GitHub
parent 6fda81d4f5
commit 56b8de1699
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 1 deletions

View File

@ -63,6 +63,16 @@ loop to remain active. If there is no other activity keeping the event loop
running, the process may exit before the `Immediate` object's callback is
invoked. Calling `immediate.unref()` multiple times will have no effect.
### `immediate[Symbol.dispose]()`
<!-- YAML
added: REPLACEME
-->
> Stability: 1 - Experimental
Cancels the immediate. This is similar to calling `clearImmediate()`.
## Class: `Timeout`
This object is created internally and is returned from [`setTimeout()`][] and
@ -157,6 +167,16 @@ across [`worker_threads`][] it must first be passed to the correct
thread. This allows enhanced compatibility with browser
`setTimeout()` and `setInterval()` implementations.
### `timeout[Symbol.dispose]()`
<!-- YAML
added: REPLACEME
-->
> Stability: 1 - Experimental
Cancels the timeout.
## Scheduling timers
A timer in Node.js is an internal construct that calls a given function after

View File

@ -228,7 +228,7 @@ function copyPrototype(src, dest, prefix) {
copyPrototype(original.prototype, primordials, `${name}Prototype`);
});
// Define Symbol.Dispose and Symbol.AsyncDispose
// Define Symbol.dispose and Symbol.asyncDispose
// Until these are defined by the environment.
// TODO(MoLow): Remove this polyfill once Symbol.dispose and Symbol.asyncDispose are available in V8.
primordials.SymbolDispose ??= primordials.SymbolFor('nodejs.dispose');

View File

@ -24,6 +24,7 @@
const {
MathTrunc,
ObjectDefineProperty,
SymbolDispose,
SymbolToPrimitive,
} = primordials;
@ -253,6 +254,10 @@ Timeout.prototype.close = function() {
return this;
};
Timeout.prototype[SymbolDispose] = function() {
clearTimeout(this);
};
/**
* Coerces a `Timeout` to a primitive.
* @returns {number}
@ -338,6 +343,10 @@ function clearImmediate(immediate) {
immediateQueue.remove(immediate);
}
Immediate.prototype[SymbolDispose] = function() {
clearImmediate(this);
};
module.exports = {
setTimeout,
clearTimeout,

View File

@ -0,0 +1,18 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const timer = setTimeout(common.mustNotCall(), 10);
const interval = setInterval(common.mustNotCall(), 10);
const immediate = setImmediate(common.mustNotCall());
timer[Symbol.dispose]();
interval[Symbol.dispose]();
immediate[Symbol.dispose]();
process.on('exit', () => {
assert.strictEqual(timer._destroyed, true);
assert.strictEqual(interval._destroyed, true);
assert.strictEqual(immediate._destroyed, true);
});