summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Argasinski <argasinski.hubert@gmail.com>2016-04-12 01:44:30 -0700
committerGraeme Yeates <yeatesgraeme@gmail.com>2016-04-12 18:46:35 -0400
commit385c0550d0822b49e2205bdfffa24106c7ef4c64 (patch)
tree62ab1510e13c6cc7bcc7e3b50237782c483642b6
parentd9675a9032ed86048620a83d3e6bc636fef370b2 (diff)
downloadasync-385c0550d0822b49e2205bdfffa24106c7ef4c64.tar.gz
jsdoc-style documentation for `Control Flow` methods
this should be the last of the public methods requiring documentaiton
-rw-r--r--lib/auto.js77
-rw-r--r--lib/autoInject.js86
-rw-r--r--lib/cargo.js76
-rw-r--r--lib/iterator.js32
-rw-r--r--lib/priorityQueue.js23
-rw-r--r--lib/queue.js96
-rw-r--r--lib/race.js2
-rw-r--r--lib/retry.js57
-rw-r--r--lib/retryable.js23
-rw-r--r--lib/times.js3
-rw-r--r--lib/timesLimit.js2
-rw-r--r--lib/timesSeries.js2
12 files changed, 475 insertions, 4 deletions
diff --git a/lib/auto.js b/lib/auto.js
index afca933..b37970e 100644
--- a/lib/auto.js
+++ b/lib/auto.js
@@ -11,6 +11,83 @@ import rest from 'lodash/rest';
import onlyOnce from './internal/onlyOnce';
+/**
+ * Determines the best order for running the functions in `tasks`, based on
+ * their requirements. Each function can optionally depend on other functions
+ *nbeing completed first, and each function is run as soon as its requirements
+ * are satisfied.
+ *
+ * If any of the functions pass an error to their callback, the `auto` sequence
+ * will stop. Further tasks will not execute (so any other functions depending
+ * on it will not run), and the main `callback` is immediately called with the
+ * error.
+ *
+ * Functions also receive an object containing the results of functions which
+ * have completed so far as the first argument, if they have dependencies. If a
+ * task function has no dependencies, it will only be passed a callback.
+ *
+ * @name auto
+ * @static
+ * @memberOf async
+ * @category Control Flow
+ * @param {Object} tasks - An object. Each of its properties is either a
+ * function or an array of requirements, with the function itself the last item
+ * in the array. The object's key of a property serves as the name of the task
+ * defined by that property, i.e. can be used when specifying requirements for
+ * other tasks. The function receives one or two arguments:
+ * * a `results` object, containing the results of the previously executed
+ * functions, only passed if the task has any dependencies,
+ * * a `callback(err, result)` function, which must be called when finished,
+ * passing an `error` (which can be `null`) and the result of the function's
+ * execution.
+ * @param {number} [concurrency=Infinity] - An optional `integer` for
+ * determining the maximum number of tasks that can be run in parallel. By
+ * default, as many as possible.
+ * @param {Function} [callback] - An optional callback which is called when all
+ * the tasks have been completed. It receives the `err` argument if any `tasks`
+ * pass an error to their callback. Results are always returned; however, if an
+ * error occurs, no further `tasks` will be performed, and the results object
+ * will only contain partial results. Invoked with (err, results).
+ * @example
+ *
+ * async.auto({
+ * // this function will just be passed a callback
+ * readData: async.apply(fs.readFile, 'data.txt', 'utf-8'),
+ * showData: ['readData', function(results, cb) {
+ * // results.readData is the file's contents
+ * // ...
+ * }]
+ * }, callback);
+ *
+ * async.auto({
+ * get_data: function(callback) {
+ * console.log('in get_data');
+ * // async code to get some data
+ * callback(null, 'data', 'converted to array');
+ * },
+ * make_folder: function(callback) {
+ * console.log('in make_folder');
+ * // async code to create a directory to store a file in
+ * // this is run at the same time as getting the data
+ * callback(null, 'folder');
+ * },
+ * write_file: ['get_data', 'make_folder', function(results, callback) {
+ * console.log('in write_file', JSON.stringify(results));
+ * // once there is some data and the directory exists,
+ * // write the data to a file in the directory
+ * callback(null, 'filename');
+ * }],
+ * email_link: ['write_file', function(results, callback) {
+ * console.log('in email_link', JSON.stringify(results));
+ * // once the file is written let's email a link to it...
+ * // results.write_file contains the filename returned by write_file.
+ * callback(null, {'file':results.write_file, 'email':'user@example.com'});
+ * }]
+ * }, function(err, results) {
+ * console.log('err = ', err);
+ * console.log('results = ', results);
+ * });
+ */
export default function (tasks, concurrency, callback) {
if (typeof concurrency === 'function') {
// concurrency is optional, shift the args.
diff --git a/lib/autoInject.js b/lib/autoInject.js
index 245db8e..02324a1 100644
--- a/lib/autoInject.js
+++ b/lib/autoInject.js
@@ -10,6 +10,92 @@ function parseParams(func) {
return func.toString().match(argsRegex)[1].split(/\s*\,\s*/);
}
+/**
+ * A dependency-injected version of the [`auto`](#auto) function. Dependent
+ * tasks are specified as parameters to the function, after the usual callback
+ * parameter, with the parameter names matching the names of the tasks it
+ * depends on. This can provide even more readable task graphs which can be
+ * easier to maintain.
+ *
+ * If a final callback is specified, the task results are similarly injected,
+ * specified as named parameters after the initial error parameter.
+ *
+ * The autoInject function is purely syntactic sugar and its semantics are
+ * otherwise equivalent to [`auto`](#auto).
+ *
+ * @name autoInject
+ * @static
+ * @memberOf async
+ * @see `async.auto`
+ * @category Control Flow
+ * @param {Object} tasks - An object, each of whose properties is a function of
+ * the form 'func([dependencies...], callback). The object's key of a property
+ * serves as the name of the task defined by that property, i.e. can be used
+ * when specifying requirements for other tasks.
+ * * The `callback` parameter is a `callback(err, result)` which must be called
+ * when finished, passing an `error` (which can be `null`) and the result of
+ * the function's execution. The remaining parameters name other tasks on
+ * which the task is dependent, and the results from those tasks are the
+ * arguments of those parameters.
+ * @param {Function} [callback] - An optional callback which is called when all
+ * the tasks have been completed. It receives the `err` argument if any `tasks`
+ * pass an error to their callback. The remaining parameters are task names
+ * whose results you are interested in. This callback will only be called when
+ * all tasks have finished or an error has occurred, and so do not specify
+ * dependencies in the same way as `tasks` do. If an error occurs, no further
+ * `tasks` will be performed, and `results` will only be valid for those tasks
+ * which managed to complete. Invoked with (err, [results...]).
+ * @example
+ *
+ * // The example from `auto` can be rewritten as follows:
+ * async.autoInject({
+ * get_data: function(callback) {
+ * // async code to get some data
+ * callback(null, 'data', 'converted to array');
+ * },
+ * make_folder: function(callback) {
+ * // async code to create a directory to store a file in
+ * // this is run at the same time as getting the data
+ * callback(null, 'folder');
+ * },
+ * write_file: function(get_data, make_folder, callback) {
+ * // once there is some data and the directory exists,
+ * // write the data to a file in the directory
+ * callback(null, 'filename');
+ * },
+ * email_link: function(write_file, callback) {
+ * // once the file is written let's email a link to it...
+ * // write_file contains the filename returned by write_file.
+ * callback(null, {'file':write_file, 'email':'user@example.com'});
+ * }
+ * }, function(err, email_link) {
+ * console.log('err = ', err);
+ * console.log('email_link = ', email_link);
+ * });
+ *
+ * // If you are using a JS minifier that mangles parameter names, `autoInject`
+ * // will not work with plain functions, since the parameter names will be
+ * // collapsed to a single letter identifier. To work around this, you can
+ * // explicitly specify the names of the parameters your task function needs
+ * // in an array, similar to Angular.js dependency injection. The final
+ * // results callback can be provided as an array in the same way.
+ *
+ * // This still has an advantage over plain `auto`, since the results a task
+ * // depends on are still spread into arguments.
+ * async.autoInject({
+ * //...
+ * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
+ * callback(null, 'filename');
+ * }],
+ * email_link: ['write_file', function(write_file, callback) {
+ * callback(null, {'file':write_file, 'email':'user@example.com'});
+ * }]
+ * //...
+ * }, ['email_link', function(err, email_link) {
+ * console.log('err = ', err);
+ * console.log('email_link = ', email_link);
+ * }]);
+ */
export default function autoInject(tasks, callback) {
var newTasks = {};
diff --git a/lib/cargo.js b/lib/cargo.js
index b90ab0f..faa4ab4 100644
--- a/lib/cargo.js
+++ b/lib/cargo.js
@@ -2,6 +2,82 @@
import queue from './internal/queue';
+/**
+ * A cargo of tasks for the worker function to complete. Cargo inherits all of
+ * the same methods and event callbacks as [`queue`](#queue).
+ * @typedef {Object} cargo
+ * @property {Function} length - A function returning the number of items
+ * waiting to be processed. Invoke with ().
+ * @property {number} payload - An `integer` for determining how many tasks
+ * should be process per round. This property can be changed after a `cargo` is
+ * created to alter the payload on-the-fly.
+ * @property {Function} push - Adds `task` to the `queue`. The callback is
+ * called once the `worker` has finished processing the task. Instead of a
+ * single task, an array of `tasks` can be submitted. The respective callback is
+ * used for every task in the list. Invoke with (task, [callback]).
+ * @property {Function} saturated - A callback that is called when the
+ * `queue.length()` hits the concurrency and further tasks will be queued.
+ * @property {Function} empty - A callback that is called when the last item
+ * from the `queue` is given to a `worker`.
+ * @property {Function} drain - A callback that is called when the last item
+ * from the `queue` has returned from the `worker`.
+ * @property {Function} idle - a function returning false if there are items
+ * waiting or being processed, or true if not. Invoke with ().
+ * @property {Function} pause - a function that pauses the processing of tasks
+ * until `resume()` is called. Invoke with ().
+ * @property {Function} resume - a function that resumes the processing of
+ * queued tasks when the queue is paused. Invoke with ().
+ * @property {Function} kill - a function that removes the `drain` callback and
+ * empties remaining tasks from the queue forcing it to go idle. Invoke with ().
+ */
+
+/**
+ * Creates a `cargo` object with the specified payload. Tasks added to the
+ * cargo will be processed altogether (up to the `payload` limit). If the
+ * `worker` is in progress, the task is queued until it becomes available. Once
+ * the `worker` has completed some tasks, each callback of those tasks is
+ * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
+ * for how `cargo` and `queue` work.
+ *
+ * While [queue](#queue) passes only one task to one of a group of workers
+ * at a time, cargo passes an array of tasks to a single worker, repeating
+ * when the worker is finished.
+ *
+ * @name cargo
+ * @static
+ * @memberOf async
+ * @see `async.queue`
+ * @category Control Flow
+ * @param {Function} worker - An asynchronous function for processing an array
+ * of queued tasks, which must call its `callback(err)` argument when finished,
+ * with an optional `err` argument. Invoked with (tasks, callback).
+ * @param {number} [payload=Infinity] - An optional `integer` for determining
+ * how many tasks should be processed per round; if omitted, the default is
+ * unlimited.
+ * @returns {cargo} A cargo object to manage the tasks. Callbacks can
+ * attached as certain properties to listen for specific events during the
+ * lifecycle of the cargo and inner queue.
+ * @example
+ *
+ * // create a cargo object with payload 2
+ * var cargo = async.cargo(function(tasks, callback) {
+ * for (var i=0; i<tasks.length; i++) {
+ * console.log('hello ' + tasks[i].name);
+ * }
+ * callback();
+ * }, 2);
+ *
+ * // add some items
+ * cargo.push({name: 'foo'}, function(err) {
+ * console.log('finished processing foo');
+ * });
+ * cargo.push({name: 'bar'}, function(err) {
+ * console.log('finished processing bar');
+ * });
+ * cargo.push({name: 'baz'}, function(err) {
+ * console.log('finished processing baz');
+ * });
+ */
export default function cargo(worker, payload) {
return queue(worker, 1, payload);
}
diff --git a/lib/iterator.js b/lib/iterator.js
index 568171a..7d1b0f9 100644
--- a/lib/iterator.js
+++ b/lib/iterator.js
@@ -1,5 +1,37 @@
'use strict';
+/**
+ * Creates an iterator function which calls the next function in the `tasks`
+ * array, returning a continuation to call the next one after that. It's also
+ * possible to “peek” at the next iterator with `iterator.next()`.
+ *
+ * This function is used internally by the `async` module, but can be useful
+ * when you want to manually control the flow of functions in series.
+ *
+ * @name iterator
+ * @static
+ * @memberOf async
+ * @category Control Flow
+ * @param {Array} tasks - An array of functions to run.
+ * @returns The next function to run in the series.
+ * @example
+ *
+ * var iterator = async.iterator([
+ * function() { sys.p('one'); },
+ * function() { sys.p('two'); },
+ * function() { sys.p('three'); }
+ * ]);
+ *
+ * node> var iterator2 = iterator();
+ * 'one'
+ * node> var iterator3 = iterator2();
+ * 'two'
+ * node> iterator3();
+ * 'three'
+ * node> var nextfn = iterator2.next();
+ * node> nextfn();
+ * 'three'
+ */
export default function(tasks) {
function makeCallback(index) {
function fn() {
diff --git a/lib/priorityQueue.js b/lib/priorityQueue.js
index 90ca03e..a33f2f5 100644
--- a/lib/priorityQueue.js
+++ b/lib/priorityQueue.js
@@ -8,6 +8,29 @@ import setImmediate from './setImmediate';
import queue from './queue';
+/**
+ * The same as [`queue`](#queue) only tasks are assigned a priority and
+ * completed in ascending priority order.
+ *
+ * @name priorityQueue
+ * @static
+ * @memberOf async
+ * @see `async.queue`
+ * @category Control Flow
+ * @param {Function} worker - An asynchronous function for processing a queued
+ * task, which must call its `callback(err)` argument when finished, with an
+ * optional `error` as an argument. If you want to handle errors from an
+ * individual task, pass a callback to `q.push()`. Invoked with
+ * (task, callback).
+ * @param {number} concurrency - An `integer` for determining how many `worker`
+ * functions should be run in parallel. If omitted, the concurrency defaults to
+ * `1`. If the concurrency is `0`, an error is thrown.
+ * @returns {queue} A priorityQueue object to manage the tasks. There are two
+ * differences between `queue` and `priorityQueue` objects:
+ * * `push(task, priority, [callback])` - `priority` should be a number. If an
+ * array of `tasks` is given, all tasks will be assigned the same priority.
+ * * The `unshift` method was removed.
+ */
export default function(worker, concurrency) {
function _compareTasks(a, b) {
return a.priority - b.priority;
diff --git a/lib/queue.js b/lib/queue.js
index de2ac93..683f227 100644
--- a/lib/queue.js
+++ b/lib/queue.js
@@ -2,6 +2,102 @@
import queue from './internal/queue';
+/**
+ * A queue of tasks for the worker function to complete.
+ * @typedef {Object} queue
+ * @property {Function} length - a function returning the number of items
+ * waiting to be processed. Invoke with ().
+ * @property {Function} started - a function returning whether or not any
+ * items have been pushed and processed by the queue. Invoke with ().
+ * @property {Function} running - a function returning the number of items
+ * currently being processed. Invoke with ().
+ * @property {Function} workersList - a function returning the array of items
+ * currently being processed. Invoke with ().
+ * @property {Function} idle - a function returning false if there are items
+ * waiting or being processed, or true if not. Invoke with ().
+ * @property {number} concurrency - an integer for determining how many `worker`
+ * functions should be run in parallel. This property can be changed after a
+ * `queue` is created to alter the concurrency on-the-fly.
+ * @property {Function} push - add a new task to the `queue`. Calls `callback`
+ * once the `worker` has finished processing the task. Instead of a single task,
+ * a `tasks` array can be submitted. The respective callback is used for every
+ * task in the list. Invoke with (task, [callback]),
+ * @property {Function} unshift - add a new task to the front of the `queue`.
+ * Invoke with (task, [callback]).
+ * @property {Function} saturated - a callback that is called when the number of
+ * running workers hits the `concurrency` limit, and further tasks will be
+ * queued.
+ * @property {Function} unsaturated - a callback that is called when the number
+ * of running workers is less than the `concurrency` & `buffer` limits, and
+ * further tasks will not be queued.
+ * @property {number} buffer - A minimum threshold buffer in order to say that
+ * the `queue` is `unsaturated`.
+ * @property {Function} empty - a callback that is called when the last item
+ * from the `queue` is given to a `worker`.
+ * @property {Function} drain - a callback that is called when the last item
+ * from the `queue` has returned from the `worker`.
+ * @property {boolean} paused - a boolean for determining whether the queue is
+ * in a paused state.
+ * @property {Function} pause - a function that pauses the processing of tasks
+ * until `resume()` is called. Invoke with ().
+ * @property {Function} resume - a function that resumes the processing of
+ * queued tasks when the queue is paused. Invoke with ().
+ * @property {Function} kill - a function that removes the `drain` callback and
+ * empties remaining tasks from the queue forcing it to go idle. Invoke with ().
+ */
+
+/**
+ * Creates a `queue` object with the specified `concurrency`. Tasks added to the
+ * `queue` are processed in parallel (up to the `concurrency` limit). If all
+ * `worker`s are in progress, the task is queued until one becomes available.
+ * Once a `worker` completes a `task`, that `task`'s callback is called.
+ *
+ * @name queue
+ * @static
+ * @memberOf async
+ * @category Control Flow
+ * @param {Function} worker - An asynchronous function for processing a queued
+ * task, which must call its `callback(err)` argument when finished, with an
+ * optional `error` as an argument. If you want to handle errors from an
+ * individual task, pass a callback to `q.push()`. Invoked with
+ * (task, callback).
+ * @param {number} [concurrency=1] - An `integer` for determining how many
+ * `worker` functions should be run in parallel. If omitted, the concurrency
+ * defaults to `1`. If the concurrency is `0`, an error is thrown.
+ * @returns {queue} A queue object to manage the tasks. Callbacks can
+ * attached as certain properties to listen for specific events during the
+ * lifecycle of the queue.
+ * @example
+ *
+ * // create a queue object with concurrency 2
+ * var q = async.queue(function(task, callback) {
+ * console.log('hello ' + task.name);
+ * callback();
+ * }, 2);
+ *
+ * // assign a callback
+ * q.drain = function() {
+ * console.log('all items have been processed');
+ * };
+ *
+ * // add some items to the queue
+ * q.push({name: 'foo'}, function(err) {
+ * console.log('finished processing foo');
+ * });
+ * q.push({name: 'bar'}, function (err) {
+ * console.log('finished processing bar');
+ * });
+ *
+ * // add some items to the queue (batch-wise)
+ * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
+ * console.log('finished processing item');
+ * });
+ *
+ * // add some items to the front of the queue
+ * q.unshift({name: 'bar'}, function (err) {
+ * console.log('finished processing bar');
+ * });
+ */
export default function (worker, concurrency) {
return queue(function (items, cb) {
worker(items[0], cb);
diff --git a/lib/race.js b/lib/race.js
index b12b2e7..f797b85 100644
--- a/lib/race.js
+++ b/lib/race.js
@@ -14,7 +14,7 @@ import once from './internal/once';
* @name race
* @static
* @memberOf async
- * @category Util
+ * @category Control Flow
* @param {Array} tasks - An array containing functions to run. Each function
* is passed a `callback(err, result)` which it must call on completion with an
* error `err` (which can be `null`) and an optional `result` value.
diff --git a/lib/retry.js b/lib/retry.js
index aecd07f..df80383 100644
--- a/lib/retry.js
+++ b/lib/retry.js
@@ -3,6 +3,63 @@
import series from './series';
import noop from 'lodash/noop';
+/**
+ * Attempts to get a successful response from `task` no more than `times` times
+ * before returning an error. If the task is successful, the `callback` will be
+ * passed the result of the successful task. If all attempts fail, the callback
+ * will be passed the error and result (if any) of the final attempt.
+ *
+ * @name retry
+ * @static
+ * @memberOf async
+ * @category Control Flow
+ * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an
+ * object with `times` and `interval` or a number.
+ * * `times` - The number of attempts to make before giving up. The default
+ * is `5`.
+ * * `interval` - The time to wait between retries, in milliseconds. The
+ * default is `0`.
+ * * If `opts` is a number, the number specifies the number of times to retry,
+ * with the default interval of `0`.
+ * @param {Function} task - A function which receives two arguments: (1) a
+ * `callback(err, result)` which must be called when finished, passing `err`
+ * (which can be `null`) and the `result` of the function's execution, and (2)
+ * a `results` object, containing the results of the previously executed
+ * functions (if nested inside another control flow). Invoked with
+ * (callback, results).
+ * @param {Function} [callback] - An optional callback which is called when the
+ * task has succeeded, or after the final failed attempt. It receives the `err`
+ * and `result` arguments of the last attempt at completing the `task`. Invoked
+ * with (err, results).
+ * @example
+ *
+ * // The `retry` function can be used as a stand-alone control flow by passing
+ * // a callback, as shown below:
+ *
+ * // try calling apiMethod 3 times
+ * async.retry(3, apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
+ * // try calling apiMethod 3 times, waiting 200 ms between each retry
+ * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
+ * // try calling apiMethod the default 5 times no delay between each retry
+ * async.retry(apiMethod, function(err, result) {
+ * // do something with the result
+ * });
+ *
+ * // It can also be embedded within other control flow functions to retry
+ * // individual methods that are not as reliable, like this:
+ * async.auto({
+ * users: api.getUsers.bind(api),
+ * payments: async.retry(3, api.getPayments.bind(api))
+ * }, function(err, results) {
+ * // do something with the results
+ * });
+ */
export default function retry(times, task, callback) {
var DEFAULT_TIMES = 5;
var DEFAULT_INTERVAL = 0;
diff --git a/lib/retryable.js b/lib/retryable.js
index f01d9b9..58f56f4 100644
--- a/lib/retryable.js
+++ b/lib/retryable.js
@@ -1,6 +1,29 @@
import retry from './retry';
import initialParams from './internal/initialParams';
+/**
+ * A close relative of `retry`. This method wraps a task and makes it
+ * retryable, rather than immediately calling it with retries.
+ *
+ * @name retryable
+ * @static
+ * @memberOf async
+ * @see `async.retry`
+ * @category Control Flow
+ * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional
+ * options, exactly the same as from `retry`
+ * @param {Function} task - the asynchronous function to wrap
+ * @returns {Functions} The wrapped function, which when invoked, will retry on
+ * an error, based on the parameters specified in `opts`.
+ * @example
+ *
+ * async.auto({
+ * dep1: async.retryable(3, getFromFlakyService),
+ * process: ["dep1", async.retryable(3, function (results, cb) {
+ * maybeProcessData(results.dep1, cb);
+ * })]
+ * }, callback);
+ */
export default function (opts, task) {
if (!task) {
task = opts;
diff --git a/lib/times.js b/lib/times.js
index a81ba3b..ef92779 100644
--- a/lib/times.js
+++ b/lib/times.js
@@ -11,12 +11,13 @@ import doLimit from './internal/doLimit';
* @static
* @memberOf async
* @see `async.map`
- * @category Util
+ * @category Control Flow
* @param {number} n - The number of times to run the function.
* @param {Function} iteratee - The function to call `n` times. Invoked with the
* iteration index and a callback (n, next).
* @param {Function} callback - see [`map`](#map).
* @example
+ *
* // Pretend this is some complicated async factory
* var createUser = function(id, callback) {
* callback(null, {
diff --git a/lib/timesLimit.js b/lib/timesLimit.js
index 73ae4d1..abec4f8 100644
--- a/lib/timesLimit.js
+++ b/lib/timesLimit.js
@@ -11,7 +11,7 @@ import range from 'lodash/_baseRange';
* @static
* @memberOf async
* @see `async.times`
- * @category Util
+ * @category Control Flow
* @param {number} n - The number of times to run the function.
* @param {number} limit - The maximum number of async operations at a time.
* @param {Function} iteratee - The function to call `n` times. Invoked with the
diff --git a/lib/timesSeries.js b/lib/timesSeries.js
index dd2ad45..e68d1ed 100644
--- a/lib/timesSeries.js
+++ b/lib/timesSeries.js
@@ -10,7 +10,7 @@ import doLimit from './internal/doLimit';
* @static
* @memberOf async
* @see `async.times`
- * @category Util
+ * @category Control Flow
* @param {number} n - The number of times to run the function.
* @param {Function} iteratee - The function to call `n` times. Invoked with the
* iteration index and a callback (n, next).