Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 36 additions & 8 deletions lib/node_modules/@stdlib/utils/async/any-by/lib/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,30 +126,58 @@ function factory( options, predicate ) {
* @param {Callback} done - function to invoke upon completion
* @throws {TypeError} first argument must be a collection
* @throws {TypeError} last argument must be a function
* @returns {void}
* @returns {Object} status object for monitoring the operation
*/
function anyByAsync( collection, done ) {
var status = {
'status': 'pending',
'ndone': 0,
'nerrors': 0
};

if ( !isCollection( collection ) ) {
throw new TypeError( format( 'invalid argument. First argument must be a collection. Value: `%s`.', collection ) );
}
if ( !isFunction( done ) ) {
throw new TypeError( format( 'invalid argument. Last argument must be a function. Value: `%s`.', done ) );
}
return limit( collection, opts, f, clbk );

if ( collection.length === 0 ) {
status.status = 'ok';
setImmediate( onTimeout );
return status;
}

// Pass a wrapper to limit so we can update our status object before calling the final done:
limit( collection, opts, f, onFinal );
return status;

/**
* Callback invoked upon an empty collection.
*
* @private
*/
function onTimeout() {
done( null, false );
}

/**
* Callback invoked upon completion.
* Internal callback to update status and trigger the user-provided done function.
*
* @private
* @param {*} [error] - error
* @param {boolean} bool - test result
* @param {*} [error] - error object
* @param {boolean} [bool] - test result
* @returns {void}
*/
function clbk( error, bool ) {
function onFinal( error, bool ) {
if ( error ) {
return done( error, false );
status.status = 'fail';
status.nerrors = 1;
return done( error, false ); // Explicitly pass false here
}
done( null, bool );
status.status = 'ok';
status.ndone = collection.length;
done( null, !!bool );
}
}
}
Expand Down
65 changes: 53 additions & 12 deletions lib/node_modules/@stdlib/utils/async/for-each/lib/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,45 +107,86 @@ function factory( options, fcn ) {
f = options;
}
if ( !isFunction( f ) ) {
throw new TypeError( format( 'invalid argument. Last argument must be a function. Value: `%s`.', f ) );
throw new TypeError( format( 'invalid argument. Last argument must be a function. Value: `%', f ) );
}
if ( opts.series ) {
opts.limit = 1;
} else if ( !opts.limit ) {
opts.limit = PINF;
}

return forEachAsync;

/**
* Invokes a function for each element in a collection.
*
* @private
* @param {Collection} collection - input collection
* @param {Callback} done - function to invoke upon completion
* @throws {TypeError} first argument must be a collection
* @throws {TypeError} last argument must be a function
* @returns {void}
*/
* Invokes a function for each element in a collection.
*
* @private
* @param {Collection} collection - input collection
* @param {Callback} done - function to invoke upon completion
* @throws {TypeError} first argument must be a collection
* @throws {TypeError} last argument must be a function
* @returns {Object} status object
*/
function forEachAsync( collection, done ) {
// Status object
var status = {
'status': 'pending',
'ndone': 0,
'nerrors': 0
};
if ( !isCollection( collection ) ) {
throw new TypeError( format( 'invalid argument. First argument must be a collection. Value: `%s`.', collection ) );
}
if ( !isFunction( done ) ) {
throw new TypeError( format( 'invalid argument. Last argument must be a function. Value: `%s`.', done ) );
}
return limit( collection, opts, f, clbk );

/**
* Wrapper function to invoke the iterator.
*
* @private
* @param {*} value - iterated value
* @param {number} index - iteration index
* @param {Collection} collection - input collection
* @param {Function} next - callback to invoke after processing an element
*/
function wrapped( value, index, collection, next ) {
f.call( opts.thisArg, value, index, collection, onDone );

/**
* Callback invoked upon completion.
*
* @private
* @param {(Error|null)} error - error object
* @returns {void}
*/
function onDone( error ) {
if ( error ) {
status.nerrors += 1;
return next( error );
}
// Hook successful completion:
status.ndone += 1; // 'this' must be the returned function object
next();
}
}

limit( collection, opts, wrapped.bind(status), clbk );
return status;

/**
* Callback invoked upon completion.
*
* @private
* @param {*} [error] - error
* @param {*} [error] - error object
* @returns {void}
*/
function clbk( error ) {
if ( error ) {
status.status = 'fail';
return done( error );
}
status.status = 'ok';
done();
}
}
Expand Down
53 changes: 41 additions & 12 deletions lib/node_modules/@stdlib/utils/async/for-each/test/test.factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ tape( 'the returned function invokes a provided function once for each element i

forEachAsync( arr, done );

function fcn( value, next ) {
function fcn( value, index, collection, next ) {
i += 1;
t.strictEqual( value, expected[ i ], 'provides expected value' );

Expand Down Expand Up @@ -368,7 +368,7 @@ tape( 'the returned function invokes a provided function once for each element i

forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index,collection, next ) {
i += 1;
t.strictEqual( value, expected[ index ], 'provides expected value' );
t.strictEqual( index, i, 'provides expected index' );
Expand Down Expand Up @@ -519,7 +519,7 @@ tape( 'by default, the returned function processes collection elements concurren

forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
setTimeout( onTimeout, value );

function onTimeout() {
Expand Down Expand Up @@ -557,7 +557,7 @@ tape( 'the function supports returning a function for processing collection elem

forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
setTimeout( onTimeout, value );

function onTimeout() {
Expand Down Expand Up @@ -596,7 +596,7 @@ tape( 'the function supports returning a function for processing collection elem

forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
setTimeout( onTimeout, value );

function onTimeout() {
Expand Down Expand Up @@ -635,7 +635,7 @@ tape( 'the function supports returning a function which limits the maximum numbe

forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
setTimeout( onTimeout, value );

function onTimeout() {
Expand Down Expand Up @@ -672,7 +672,7 @@ tape( 'the function supports specifying an execution context for the invoked fun
arr = [ 1, 2, 3 ];
forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
/* eslint-disable no-invalid-this */
this.count += 1;
setTimeout( onTimeout, value );
Expand Down Expand Up @@ -709,7 +709,7 @@ tape( 'if an error is encountered while processing a collection element, the ret

forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
setTimeout( onTimeout, value );

function onTimeout() {
Expand Down Expand Up @@ -745,7 +745,7 @@ tape( 'if an error is encountered while processing a collection element, the ret

forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
count += 1;
setTimeout( onTimeout, value );

Expand Down Expand Up @@ -779,7 +779,7 @@ tape( 'if an error is encountered while processing a collection element, the ret
count = 0;
forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
count += 1;
setTimeout( onTimeout, value );

Expand Down Expand Up @@ -813,7 +813,7 @@ tape( 'if an error is encountered while processing a collection element, the ret
count = 0;
forEachAsync( arr, done );

function fcn( value, index, next ) {
function fcn( value, index, collection, next ) {
count += 1;
setTimeout( onTimeout, value );

Expand Down Expand Up @@ -869,7 +869,7 @@ tape( 'the returned function does not guarantee asynchronous execution', functio
forEachAsync( arr, done );
i = 1;

function fcn( value, next ) {
function fcn( value, index, collection, next ) {
next();
}

Expand All @@ -883,3 +883,32 @@ tape( 'the returned function does not guarantee asynchronous execution', functio
t.end();
}
});

tape( 'the returned function returns a status object', function test( t ) {
var forEachAsync;
var status;
var arr;

forEachAsync = factory( fcn );
arr = [ 1, 2, 3 ];

status = forEachAsync( arr, done );

t.strictEqual( typeof status, 'object', 'returns an object' );
t.strictEqual( status.status, 'pending', 'initial status is pending' );
t.strictEqual( status.ndone, 0, 'initial ndone is 0' );
t.strictEqual( status.nerrors, 0, 'initial nerrors is 0' );

function fcn( value, index, collection, next ) {
setTimeout( onTimeout, 10 );
function onTimeout() {
next();
}
}

function done() {
t.strictEqual( status.status, 'ok', 'final status is ok' );
t.strictEqual( status.ndone, 3, 'final ndone is 3' );
t.end();
}
});
Loading
Loading