diff options
author | Augusto Franzoia <ajfranzoia@gmail.com> | 2016-03-07 00:57:22 -0300 |
---|---|---|
committer | Augusto Franzoia <ajfranzoia@gmail.com> | 2016-03-07 00:57:22 -0300 |
commit | 0d87dd08374f95df0ba1449cdbb4bc5db320dee7 (patch) | |
tree | 87e1fb4e325831d55d7ce3490201ec3ef9720a24 | |
parent | f75579366c69940dad5d4ee0b6b7070485701481 (diff) | |
download | async-0d87dd08374f95df0ba1449cdbb4bc5db320dee7.tar.gz |
Support function timeout via async.timeout wrapper
-rw-r--r-- | lib/index.js | 3 | ||||
-rw-r--r-- | lib/timeout.js | 36 | ||||
-rw-r--r-- | mocha_test/timeout.js | 48 | ||||
-rwxr-xr-x | test/test-async.js | 46 |
4 files changed, 133 insertions, 0 deletions
diff --git a/lib/index.js b/lib/index.js index 2e27f25..300491d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -55,6 +55,7 @@ import setImmediate from './setImmediate'; import some from './some'; import someLimit from './someLimit'; import sortBy from './sortBy'; +import timeout from './timeout'; import times from './times'; import timesLimit from './timesLimit'; import timesSeries from './timesSeries'; @@ -120,6 +121,7 @@ export default { some: some, someLimit: someLimit, sortBy: sortBy, + timeout: timeout, times: times, timesLimit: timesLimit, timesSeries: timesSeries, @@ -203,6 +205,7 @@ export { some as some, someLimit as someLimit, sortBy as sortBy, + timeout as timeout, times as times, timesLimit as timesLimit, timesSeries as timesSeries, diff --git a/lib/timeout.js b/lib/timeout.js new file mode 100644 index 0000000..c8c9dfd --- /dev/null +++ b/lib/timeout.js @@ -0,0 +1,36 @@ +'use strict'; + +export default function timeout(asyncFn, miliseconds) { + var originalCallback, timer; + var timedOut = false; + + function injectedCallback() { + if (!timedOut) { + originalCallback.apply(null, arguments); + clearTimeout(timer); + } + } + + function timeoutCallback() { + var error = new Error('Callback function timed out.'); + error.code = 'ETIMEDOUT'; + timedOut = true; + originalCallback(error); + } + + function injectCallback(asyncFnArgs) { + // replace callback in asyncFn args + var args = Array.prototype.slice.call(asyncFnArgs, 0); + originalCallback = args[args.length - 1]; + args[args.length - 1] = injectedCallback; + return args; + } + + function wrappedFn() { + // setup timer and call original function + timer = setTimeout(timeoutCallback, miliseconds); + asyncFn.apply(null, injectCallback(arguments)); + } + + return wrappedFn; +} diff --git a/mocha_test/timeout.js b/mocha_test/timeout.js new file mode 100644 index 0000000..8355eb6 --- /dev/null +++ b/mocha_test/timeout.js @@ -0,0 +1,48 @@ +var async = require('../lib'); +var expect = require('chai').expect; + +describe('timeout', function () { + + it('timeout with series', function(done){ + async.series([ + async.timeout(function asyncFn(callback) { + setTimeout(function() { + callback(null, 'I didn\'t time out'); + }, 50); + }, 200), + async.timeout(function asyncFn(callback) { + setTimeout(function() { + callback(null, 'I will time out'); + }, 300); + }, 150) + ], + function(err, results) { + expect(err.message).to.equal('Callback function timed out.'); + expect(err.code).to.equal('ETIMEDOUT'); + expect(results[0]).to.equal('I didn\'t time out'); + done(); + }); + }); + + it('timeout with parallel', function(done){ + async.parallel([ + async.timeout(function asyncFn(callback) { + setTimeout(function() { + callback(null, 'I didn\'t time out'); + }, 50); + }, 200), + async.timeout(function asyncFn(callback) { + setTimeout(function() { + callback(null, 'I will time out'); + }, 300); + }, 150) + ], + function(err, results) { + expect(err.message).to.equal('Callback function timed out.'); + expect(err.code).to.equal('ETIMEDOUT'); + expect(results[0]).to.equal('I didn\'t time out'); + done(); + }); + }); + +}); diff --git a/test/test-async.js b/test/test-async.js index bd103bf..b4aef6c 100755 --- a/test/test-async.js +++ b/test/test-async.js @@ -3825,3 +3825,49 @@ exports['asyncify'] = { return promises; }, {}) }; + +exports['timeout'] = function (test) { + test.expect(3); + + async.series([ + async.timeout(function asyncFn(callback) { + setTimeout(function() { + callback(null, 'I didn\'t time out'); + }, 50); + }, 200), + async.timeout(function asyncFn(callback) { + setTimeout(function() { + callback(null, 'I will time out'); + }, 300); + }, 150) + ], + function(err, results) { + test.ok(err.message === 'Callback function timed out.'); + test.ok(err.code === 'ETIMEDOUT'); + test.ok(results[0] === 'I didn\'t time out'); + test.done(); + }); +}; + +exports['timeout with parallel'] = function (test) { + test.expect(3); + + async.parallel([ + async.timeout(function asyncFn(callback) { + setTimeout(function() { + callback(null, 'I didn\'t time out'); + }, 50); + }, 200), + async.timeout(function asyncFn(callback) { + setTimeout(function() { + callback(null, 'I will time out'); + }, 300); + }, 150) + ], + function(err, results) { + test.ok(err.message === 'Callback function timed out.'); + test.ok(err.code === 'ETIMEDOUT'); + test.ok(results[0] === 'I didn\'t time out'); + test.done(); + }); +}; |