Apply a function against an accumulator and each element in a collection and return the accumulated result.
We believe in a future in which the web is a preferred environment for numerical computation. To help realize this future, we’ve built stdlib. stdlib is a standard library, with an emphasis on numerical and scientific computation, written in JavaScript (and C) for execution in browsers and in Node.js.
The library is fully decomposable, being architected in such a way that you can swap out and mix and match APIs and functionality to cater to your exact preferences and use cases.
When you use stdlib, you can be absolutely certain that you are using the most thorough, rigorous, well-written, studied, documented, tested, measured, and high-quality code out there.
To join us in bringing numerical computing to the web, get started by checking us out on GitHub, and please consider financially supporting stdlib. We greatly appreciate your continued support!
[![NPM version][npm-image]][npm-url] [![Build Status][test-image]][test-url] [![Coverage Status][coverage-image]][coverage-url]
Apply a function against an accumulator and each element in a collection and return the accumulated result.
bash
npm install @stdlib/utils-async-reduce
script
tag without installation and bundlers, use the [ES Module][es-module] available on the [esm
][esm-url] branch (see [README][esm-readme]).deno
][deno-url] branch (see [README][deno-readme] for usage intructions).umd
][umd-url] branch (see [README][umd-readme]).javascript
var reduceAsync = require( '@stdlib/utils-async-reduce' );
collection
and returns the accumulated result.javascript
function reducer( acc, value, index, next ) {
setTimeout( onTimeout, value );
function onTimeout() {
console.log( value );
acc.sum += value;
next( null, acc );
}
}
function done( error, acc ) {
if ( error ) {
throw error;
}
console.log( acc.sum );
}
var arr = [ 3000, 2500, 1000 ];
var acc = {
'sum': 0
};
reduceAsync( arr, acc, reducer, done );
/*
3000
2500
1000
6500
*/
next
callback accepts two arguments: error
and accumulator
. The second argument to the next
callback is passed as the first argument to the provided reducer
.javascript
function reducer( acc, value, index, next ) {
setTimeout( onTimeout, value );
function onTimeout() {
next( null, acc );
}
}
function done( error, out ) {
if ( error ) {
throw error;
}
console.log( out === acc );
// => true
}
var arr = [ 3000, 2500, 1000 ];
var acc = {};
reduceAsync( arr, acc, reducer, done );
options
:options.series=false
. Default: infinity
.reducer
for each collection
element. If true
, the function sets options.limit=1
. Default: true
.reducer
.collection
element concurrently, set the series
option to false
.javascript
function reducer( acc, value, index, next ) {
setTimeout( onTimeout, value );
function onTimeout() {
console.log( value );
acc.sum += value;
next( null, acc );
}
}
function done( error, acc ) {
if ( error ) {
throw error;
}
console.log( acc.sum );
}
var arr = [ 3000, 2500, 1000 ];
var acc = {
'sum': 0
};
var opts = {
'series': false
};
reduceAsync( arr, acc, opts, reducer, done );
/* =>
1000
2500
3000
6500
*/
limit
option.javascript
function reducer( acc, value, index, next ) {
setTimeout( onTimeout, value );
function onTimeout() {
console.log( value );
acc.sum += value;
next( null, acc );
}
}
function done( error, acc ) {
if ( error ) {
throw error;
}
console.log( acc.sum );
}
var arr = [ 3000, 2500, 1000 ];
var acc = {
'sum': 0
};
var opts = {
'limit': 2
};
reduceAsync( arr, acc, opts, reducer, done );
/* =>
2500
3000
1000
6500
*/
reducer
, set the thisArg
option.javascript
function reducer( acc, value, index, next ) {
this.count += 1;
setTimeout( onTimeout, value );
function onTimeout() {
acc.sum += value;
next( null, acc );
}
}
var arr = [ 3000, 2500, 1000 ];
var acc = {
'sum': 0
};
var context = {
'count': 0
};
var opts = {
'thisArg': context
};
reduceAsync( arr, acc, opts, reducer, done );
function done( error, acc ) {
if ( error ) {
throw error;
}
console.log( acc.sum );
// => 6500
console.log( context.count );
// => 3
}
reducer
is provided a maximum of five arguments:collection
.reducer
has finished processing a collection value
.length
. If reducer
accepts three arguments, reducer
is provided accumulator
, value
and next
. If reducer
accepts four arguments, reducer
is provided accumulator
, value
, index
, and next
. For every other reducer
signature, reducer
is provided all five arguments.javascript
function reducer( acc, value, i, collection, next ) {
console.log( 'collection: %s. %d: %d', collection.join( ',' ), i, value );
setTimeout( onTimeout, value );
function onTimeout() {
console.log( value );
acc.sum += value;
next( null, acc );
}
}
function done( error, acc ) {
if ( error ) {
throw error;
}
console.log( acc.sum );
}
var arr = [ 3000, 2500, 1000 ];
var acc = {
'sum': 0
};
reduceAsync( arr, acc, reducer, done );
/* =>
collection: 3000,2500,1000. 0: 3000
collection: 3000,2500,1000. 1: 2500
collection: 3000,2500,1000. 2: 1000
3000
2500
1000
6500
*/
collection
.javascript
function reducer( acc, value, index, next ) {
setTimeout( onTimeout, value );
function onTimeout() {
console.log( value );
acc.sum += value;
next( null, acc );
}
}
function done( error, acc ) {
if ( error ) {
throw error;
}
console.log( acc.sum );
}
var f = reduceAsync.factory( reducer );
var arr1 = [ 3000, 2500, 1000 ];
var acc1 = {
'sum': 0
};
f( arr1, acc1, done );
/* =>
3000
2500
1000
6500
*/
var arr2 = [ 300, 250, 100 ];
var acc2 = {
'sum': 0
};
f( arr2, acc2, done );
/* =>
300
250
100
650
*/
options
as reduceAsync()
.collection
may be either an [Array
][mdn-array], [Typed Array
][mdn-typed-array], or an array-like [Object
][mdn-object] (excluding strings
and functions
).next
callback with a truthy error
argument, the function suspends execution and immediately calls the done
callback for subsequent error
handling.done
callback with the accumulator
provided as the second argument. If provided an empty collection
, the function invokes the done
callback with the initial
value as the second argument.collection
resizing.undefined
elements.collection
elements concurrently, beware of race conditions when updating an accumulator. This is especially true when an accumulator is a primitive (e.g., a number
). In general, prefer object
accumulators, as objects are passed by reference, not by value.reduceAsync
nor the function returned by the factory
method guarantee asynchronous execution. To guarantee asynchrony, wrap the done
callback in a function which either executes at the end of the current stack (e.g., nextTick
) or during a subsequent turn of the event loop (e.g., setImmediate
, setTimeout
).javascript
var resolve = require( 'path' ).resolve;
var readFile = require( '@stdlib/fs-read-file' );
var reduceAsync = require( '@stdlib/utils-async-reduce' );
var files = [
resolve( __dirname, 'package.json' ),
resolve( __dirname, 'README.md' )
];
function done( error, acc ) {
if ( error ) {
throw error;
}
console.log( acc.count );
}
function read( acc, file, next ) {
var opts = {
'encoding': 'utf8'
};
readFile( file, opts, onFile );
function onFile( error ) {
if ( error ) {
return next( null, acc );
}
acc.count += 1;
next( null, acc );
}
}
var acc = {
'count': 0
};
reduceAsync( files, acc, read, done );