diff --git a/lib/timers.js b/lib/timers.js index d247c4001c0921..78953f25d5a17e 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -575,12 +575,21 @@ function processImmediate() { domain.enter(); immediate._callback = immediate._onImmediate; + + // Save next in case `clearImmediate(immediate)` is called from callback + var next = immediate._idleNext; + tryOnImmediate(immediate, tail); if (domain) domain.exit(); - immediate = immediate._idleNext; + // If `clearImmediate(immediate)` wasn't called from the callback, use the + // `immediate`'s next item + if (immediate._idleNext) + immediate = immediate._idleNext; + else + immediate = next; } // Only round-trip to C++ land if we have to. Calling clearImmediate() on an diff --git a/test/parallel/test-timers-clearImmediate.js b/test/parallel/test-timers-clearImmediate.js new file mode 100644 index 00000000000000..ab65b7bf1ce05d --- /dev/null +++ b/test/parallel/test-timers-clearImmediate.js @@ -0,0 +1,18 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +const N = 3; +var count = 0; +function next() { + const immediate = setImmediate(function() { + clearImmediate(immediate); + ++count; + }); +} +for (var i = 0; i < N; ++i) + next(); + +process.on('exit', () => { + assert.strictEqual(count, N, `Expected ${N} immediate callback executions`); +});