From bfbdc84738e87e0aa067b067e4b68cabbe75a793 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Wed, 10 Jun 2020 14:14:23 -0700 Subject: [PATCH] timers: allow promisified timeouts/immediates to be canceled Using the new experimental AbortController... Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/33833 Reviewed-By: Anna Henningsen Reviewed-By: Matteo Collina Reviewed-By: Gus Caplan --- doc/api/timers.md | 44 ++++++++++++- lib/timers.js | 79 ++++++++++++++++++++++-- test/parallel/test-timers-promisified.js | 54 ++++++++++++++++ 3 files changed, 171 insertions(+), 6 deletions(-) diff --git a/doc/api/timers.md b/doc/api/timers.md index a312022791f54b..3dcd1f4e475fbb 100644 --- a/doc/api/timers.md +++ b/doc/api/timers.md @@ -232,8 +232,47 @@ The [`setImmediate()`][], [`setInterval()`][], and [`setTimeout()`][] methods each return objects that represent the scheduled timers. These can be used to cancel the timer and prevent it from triggering. -It is not possible to cancel timers that were created using the promisified -variants of [`setImmediate()`][], [`setTimeout()`][]. +For the promisified variants of [`setImmediate()`][] and [`setTimeout()`][], +an [`AbortController`][] may be used to cancel the timer. When canceled, the +returned Promises will be rejected with an `'AbortError'`. + +For `setImmediate()`: + +```js +const util = require('util'); +const setImmediatePromise = util.promisify(setImmediate); + +const ac = new AbortController(); +const signal = ac.signal; + +setImmediatePromise('foobar', { signal }) + .then(console.log) + .catch((err) => { + if (err.message === 'AbortError') + console.log('The immediate was aborted'); + }); + +ac.abort(); +``` + +For `setTimeout()`: + +```js +const util = require('util'); +const setTimeoutPromise = util.promisify(setTimeout); + +const ac = new AbortController(); +const signal = ac.signal; + +setTimeoutPromise(1000, 'foobar', { signal }) + .then(console.log) + .catch((err) => { + if (err.message === 'AbortError') + console.log('The timeout was aborted'); + }); + +ac.abort(); +``` ### `clearImmediate(immediate)`