diff options
-rw-r--r-- | lib/timeout.js | 41 | ||||
-rw-r--r-- | mocha_test/timeout.js | 36 |
2 files changed, 56 insertions, 21 deletions
diff --git a/lib/timeout.js b/lib/timeout.js index 475b208..ebd81b1 100644 --- a/lib/timeout.js +++ b/lib/timeout.js @@ -43,33 +43,32 @@ import wrapAsync from './internal/wrapAsync'; * }); */ export default function timeout(asyncFn, milliseconds, info) { - var originalCallback, timer; - var timedOut = false; + var fn = wrapAsync(asyncFn); - function injectedCallback() { - if (!timedOut) { - originalCallback.apply(null, arguments); - clearTimeout(timer); - } - } + return initialParams(function (args, callback) { + var timedOut = false; + var timer; - function timeoutCallback() { - var name = asyncFn.name || 'anonymous'; - var error = new Error('Callback function "' + name + '" timed out.'); - error.code = 'ETIMEDOUT'; - if (info) { - error.info = info; + function timeoutCallback() { + var name = asyncFn.name || 'anonymous'; + var error = new Error('Callback function "' + name + '" timed out.'); + error.code = 'ETIMEDOUT'; + if (info) { + error.info = info; + } + timedOut = true; + callback(error); } - timedOut = true; - originalCallback(error); - } - var fn = wrapAsync(asyncFn); + args.push(function () { + if (!timedOut) { + callback.apply(null, arguments); + clearTimeout(timer); + } + }); - return initialParams(function (args, origCallback) { - originalCallback = origCallback; // setup timer and call original function timer = setTimeout(timeoutCallback, milliseconds); - fn.apply(null, args.concat(injectedCallback)); + fn.apply(null, args); }); } diff --git a/mocha_test/timeout.js b/mocha_test/timeout.js index be41283..cd4a751 100644 --- a/mocha_test/timeout.js +++ b/mocha_test/timeout.js @@ -69,4 +69,40 @@ describe('timeout', function () { done(); }); }); + + it('timeout with multiple calls (#1418)', function(done) { + var timeout = async.timeout(function asyncFn(n, callback) { + if (n < 1) { + setTimeout(function() { + callback(null, 'I will time out'); + }, 75); + } else { + async.setImmediate(function() { + callback(null, 'I didn\'t time out'); + }) + } + }, 50); + + async.series([ + function(cb) { + timeout(0, function(err, result) { + expect(err.message).to.equal('Callback function "asyncFn" timed out.'); + expect(err.code).to.equal('ETIMEDOUT'); + expect(err.info).to.equal(undefined); + expect(result).to.equal(undefined); + cb(); + }); + }, + function(cb) { + timeout(1, function(err, result) { + expect(err).to.equal(null); + expect(result).to.equal('I didn\'t time out'); + cb(); + }); + } + ], function(err) { + expect(err).to.equal(null); + done(); + }); + }) }); |