Skip to content

Commit 098fef6

Browse files
committed
timers: remember extra setTimeout() arguments when timeout==0
Fixes nodejs#2079.
1 parent 8082858 commit 098fef6

2 files changed

Lines changed: 69 additions & 16 deletions

File tree

lib/timers.js

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -144,19 +144,23 @@ exports.active = function(item) {
144144

145145

146146
exports.setTimeout = function(callback, after) {
147-
var timer, c, args;
147+
var timer;
148148

149149
if (after <= 0) {
150150
// Use the slow case for after == 0
151151
timer = new Timer();
152-
timer.ontimeout = callback;
153152

154-
args = Array.prototype.slice.call(arguments, 2);
155-
timer._onTimeout = function() {
156-
callback.apply(timer, args);
157-
timer.close();
153+
if (arguments.length <= 2) {
154+
timer._onTimeout = callback;
155+
} else {
156+
var args = Array.prototype.slice.call(arguments, 2);
157+
timer._onTimeout = function() {
158+
callback.apply(timer, args);
159+
timer.close();
160+
}
158161
}
159162

163+
timer.ontimeout = timer._onTimeout;
160164
timer.start(0, 0);
161165
} else {
162166
timer = { _idleTimeout: after };
@@ -166,16 +170,7 @@ exports.setTimeout = function(callback, after) {
166170
if (arguments.length <= 2) {
167171
timer._onTimeout = callback;
168172
} else {
169-
/*
170-
* Sometimes setTimeout is called with arguments, EG
171-
*
172-
* setTimeout(callback, 2000, "hello", "world")
173-
*
174-
* If that's the case we need to call the callback with
175-
* those args. The overhead of an extra closure is not
176-
* desired in the normal case.
177-
*/
178-
args = Array.prototype.slice.call(arguments, 2);
173+
var args = Array.prototype.slice.call(arguments, 2);
179174
timer._onTimeout = function() {
180175
callback.apply(timer, args);
181176
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
var common = require('../common');
23+
var assert = require('assert');
24+
25+
// https://github.com/joyent/node/issues/2079 - zero timeout drops extra args
26+
(function() {
27+
var ncalled = 0;
28+
29+
setTimeout(f, 0, 'foo', 'bar', 'baz');
30+
31+
function f(a, b, c) {
32+
assert.equal(a, 'foo');
33+
assert.equal(b, 'bar');
34+
assert.equal(c, 'baz');
35+
ncalled++;
36+
}
37+
38+
process.on('exit', function() {
39+
assert.equal(ncalled, 1);
40+
});
41+
})();
42+
43+
(function() {
44+
var ncalled = 0;
45+
46+
var iv = setInterval(f, 0, 'foo', 'bar', 'baz');
47+
48+
function f(a, b, c) {
49+
assert.equal(a, 'foo');
50+
assert.equal(b, 'bar');
51+
assert.equal(c, 'baz');
52+
if (++ncalled == 3) clearTimeout(iv);
53+
}
54+
55+
process.on('exit', function() {
56+
assert.equal(ncalled, 3);
57+
});
58+
})();

0 commit comments

Comments
 (0)