doUntilAsync
Invoke a function until a test condition is true.
Usage
var doUntilAsync = require( '@stdlib/utils/async/do-until' );
doUntilAsync( fcn, predicate, done[, thisArg ] )
Invokes a function until a predicate function returns true. Note that the predicate function is evaluated after executing fcn; thus, fcn always executes at least once.
function fcn( i, next ) { setTimeout( onTimeout, 0 ); function onTimeout() { console.log( 'beep: %d', i ); next(); } } function predicate( i, clbk ) { clbk( null, i >= 5 ); } function done( error ) { if ( error ) { throw error; } } doUntilAsync( fcn, predicate, done ); /* => beep: 0 beep: 1 beep: 2 beep: 3 beep: 4 */
The function to invoke is provided two arguments:
i: iteration number (starting from zero).next: a callback which must be invoked before proceeding to the next iteration.
The predicate function is provided two arguments:
i: iteration number (starting from one).clbk: a callback indicating whether to invokefcn.
The clbk function accepts two arguments:
error: error object.bool: test result.
If the test result is falsy, the function continues invoking fcn; otherwise, the function invokes the done callback.
The first argument of both clbk and next is an error argument. If either function is called with a truthy error argument, the function suspends execution and immediately calls the done callback for subsequent error handling.
function fcn( i, next ) { setTimeout( onTimeout, 0 ); function onTimeout() { next( new Error( 'beep' ) ); } } function predicate( i, clbk ) { clbk( null, i >= 5 ); } function done( error ) { console.error( error.message ); // => beep } doUntilAsync( fcn, predicate, done );
The done callback is invoked with an error argument and any arguments passed to the final next callback.
function fcn( i, next ) { setTimeout( onTimeout, 0 ); function onTimeout() { next( null, i ); } } function predicate( i, clbk ) { clbk( null, i >= 5 ); } function done( error, result ) { if ( error ) { throw error; } console.log( result ); // => 4 } doUntilAsync( fcn, predicate, done );
To set the function execution context for the invoked function, provide a thisArg.
function fcn( i, next ) { this.count += 1; setTimeout( onTimeout, 0 ); function onTimeout() { next(); } } function predicate( i, clbk ) { clbk( null, i >= 5 ); } var context = { 'count': 0 }; doUntilAsync( fcn, predicate, done, context ); function done( error ) { if ( error ) { throw error; } console.log( context.count ); // => 5 }
Notes
- Execution is not guaranteed to be asynchronous. To guarantee asynchrony, wrap the
donecallback 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).
Examples
var repeatString = require( '@stdlib/string/repeat' ); var doUntilAsync = require( '@stdlib/utils/async/do-until' ); function fcn( i, next ) { setTimeout( onTimeout, 0 ); function onTimeout() { next( null, repeatString( 'beep', i+1 ) ); } } function predicate( i, clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, i >= 5 ); } } function done( error, result ) { if ( error ) { throw error; } console.log( result ); } doUntilAsync( fcn, predicate, done );
See Also
@stdlib/utils/do-until: invoke a function until a test condition is true.@stdlib/utils/async/do-while: invoke a function while a test condition is true.@stdlib/utils/async/until: invoke a function until a test condition is true.@stdlib/utils/async/while: invoke a function while a test condition is true.