function reduce(coll, memo, iteratee, callback) {
    callback = once(callback || noop);
    var _iteratee = wrapAsync(iteratee);
    eachOfSeries(coll, function(x, i, callback) {
        _iteratee(memo, x, function(err, v) {
            memo = v;
            callback(err);
        });
    }, function(err) {
        callback(err, memo);
    });
}
Reduces `coll` into a single value using an async `iteratee` to return each
successive step. `memo` is the initial state of the reduction. This function
only operates in series.

For performance reasons, it may make sense to split a call to this function
into a parallel map, and then use the normal `Array.prototype.reduce` on the
results. This function is for situations where each step in the reduction
needs to be async; if you can get the data before reducing it, then it's
probably a good idea to do so.

@name reduce
@static
@memberOf module:Collections
@method
@alias inject
@alias foldl
@category Collection
@param {Array|Iterable|Object} coll - A collection to iterate over.
@param {*} memo - The initial state of the reduction.
@param {AsyncFunction} iteratee - A function applied to each item in the
array to produce the next step in the reduction.
The `iteratee` should complete with the next state of the reduction.
If the iteratee complete with an error, the reduction is stopped and the
main `callback` is immediately called with the error.
Invoked with (memo, item, callback).
@param {Function} [callback] - A callback which is called after all the
`iteratee` functions have finished. Result is the reduced value. Invoked with
(err, result).
@example

async.reduce([1,2,3], 0, function(memo, item, callback) {
    // pointless async:
    process.nextTick(function() {
        callback(null, memo + item)
    });
}, function(err, result) {
    // result is now equal to the last value of memo, which is 6
});