# ifthenAsync > If a predicate function returns a truthy value, invoke `x`; otherwise, invoke `y`.
## Usage ```javascript var ifthenAsync = require( '@stdlib/utils/async/if-then' ); ``` #### ifthenAsync( predicate, x, y, done ) If a `predicate` function returns a truthy value, invokes `x`; otherwise, invokes `y`. ```javascript var randu = require( '@stdlib/random/base/randu' ); function predicate( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, randu() > 0.5 ); } } function x( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, 1.0 ); } } function y( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, -1.0 ); } } function done( error, result ) { if ( error ) { throw error; } console.log( result ); } ifthenAsync( predicate, x, y, done ); ``` The `predicate` function is provided a single argument: - `clbk`: callback to invoke upon `predicate` function completion The callback accepts two arguments: - `error`: error object - `bool`: condition used to determine whether to invoke `x` or `y` Both `x` and `y` are provided a single argument: - `clbk`: callback to invoke upon function completion The callback function accepts any number of arguments, with the first argument reserved for providing an error. If the error argument is falsy, the `done` callback is invoked with its first argument as `null` and all other provided arguments. If the error argument is truthy, the `done` callback is invoked with only an error argument. ```javascript var randu = require( '@stdlib/random/base/randu' ); function predicate( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, randu() > 0.5 ); } } function x( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, 1.0, 2.0, 3.0 ); } } function y( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, 4.0, 5.0, 6.0 ); } } function done( error, a, b, c ) { if ( error ) { throw error; } console.log( a, b, c ); } ifthenAsync( predicate, x, y, done ); ```
## Notes - The function is similar to [`ifelseAsync()`][@stdlib/utils/async/if-else], but allows deferred argument evaluation. - Execution is **not** guaranteed to be asynchronous. 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`).
## Examples ```javascript var randu = require( '@stdlib/random/base/randu' ); var ceil = require( '@stdlib/math/base/special/ceil' ); var repeatString = require( '@stdlib/string/repeat' ); var ifthenAsync = require( '@stdlib/utils/async/if-then' ); var i; function next() { ifthenAsync( predicate, x, y, done ); } function predicate( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, randu() > 0.9 ); } } function x( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, repeatString( 'BOOP', ceil( randu()*3.0 ) ) ); } } function y( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, repeatString( 'beep', ceil( randu()*5.0 ) ) ); } } function done( error, result ) { if ( error ) { throw error; } i += 1; console.log( result ); if ( i < 100 ) { return next(); } } i = 0; next(); ```