import _parallel from './internal/parallel.js'
import eachOfSeries from './eachOfSeries.js'
/**
* Run the functions in the `tasks` collection in series, each one running once
* the previous function has completed. If any functions in the series pass an
* error to its callback, no more functions are run, and `callback` is
* immediately called with the value of the error. Otherwise, `callback`
* receives an array of results when `tasks` have completed.
*
* It is also possible to use an object instead of an array. Each property will
* be run as a function, and the results will be passed to the final `callback`
* as an object instead of an array. This can be a more readable way of handling
* results from {@link async.series}.
*
* **Note** that while many implementations preserve the order of object
* properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)
* explicitly states that
*
* > The mechanics and order of enumerating the properties is not specified.
*
* So if you rely on the order in which your series of functions are executed,
* and want this to work on all platforms, consider using an array.
*
* @name series
* @static
* @memberOf module:ControlFlow
* @method
* @category Control Flow
* @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing
* [async functions]{@link AsyncFunction} to run in series.
* Each function can complete with any number of optional `result` values.
* @param {Function} [callback] - An optional callback to run once all the
* functions have completed. This function gets a results array (or object)
* containing all the result arguments passed to the `task` callbacks. Invoked
* with (err, result).
* @return {Promise} a promise, if no callback is passed
* @example
*
* //Using Callbacks
* async.series([
* function(callback) {
* setTimeout(function() {
* // do some async task
* callback(null, 'one');
* }, 200);
* },
* function(callback) {
* setTimeout(function() {
* // then do another async task
* callback(null, 'two');
* }, 100);
* }
* ], function(err, results) {
* console.log(results);
* // results is equal to ['one','two']
* });
*
* // an example using objects instead of arrays
* async.series({
* one: function(callback) {
* setTimeout(function() {
* // do some async task
* callback(null, 1);
* }, 200);
* },
* two: function(callback) {
* setTimeout(function() {
* // then do another async task
* callback(null, 2);
* }, 100);
* }
* }, function(err, results) {
* console.log(results);
* // results is equal to: { one: 1, two: 2 }
* });
*
* //Using Promises
* async.series([
* function(callback) {
* setTimeout(function() {
* callback(null, 'one');
* }, 200);
* },
* function(callback) {
* setTimeout(function() {
* callback(null, 'two');
* }, 100);
* }
* ]).then(results => {
* console.log(results);
* // results is equal to ['one','two']
* }).catch(err => {
* console.log(err);
* });
*
* // an example using an object instead of an array
* async.series({
* one: function(callback) {
* setTimeout(function() {
* // do some async task
* callback(null, 1);
* }, 200);
* },
* two: function(callback) {
* setTimeout(function() {
* // then do another async task
* callback(null, 2);
* }, 100);
* }
* }).then(results => {
* console.log(results);
* // results is equal to: { one: 1, two: 2 }
* }).catch(err => {
* console.log(err);
* });
*
* //Using async/await
* async () => {
* try {
* let results = await async.series([
* function(callback) {
* setTimeout(function() {
* // do some async task
* callback(null, 'one');
* }, 200);
* },
* function(callback) {
* setTimeout(function() {
* // then do another async task
* callback(null, 'two');
* }, 100);
* }
* ]);
* console.log(results);
* // results is equal to ['one','two']
* }
* catch (err) {
* console.log(err);
* }
* }
*
* // an example using an object instead of an array
* async () => {
* try {
* let results = await async.parallel({
* one: function(callback) {
* setTimeout(function() {
* // do some async task
* callback(null, 1);
* }, 200);
* },
* two: function(callback) {
* setTimeout(function() {
* // then do another async task
* callback(null, 2);
* }, 100);
* }
* });
* console.log(results);
* // results is equal to: { one: 1, two: 2 }
* }
* catch (err) {
* console.log(err);
* }
* }
*
*/
export default function series(tasks, callback) {
return _parallel(eachOfSeries, tasks, callback);
}