# trythenAsync > If a function does not return an error, invoke a callback with the function result; otherwise, invoke a second function.
## Usage ```javascript var trythenAsync = require( '@stdlib/utils/async/try-then' ); ``` #### trythenAsync( x, y, done ) If a function `x` does not return an error, invokes a `done` callback with the function result; otherwise, invokes a second function `y`. ```javascript var randu = require( '@stdlib/random/base/randu' ); function x( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { if ( randu() > 0.5 ) { return clbk( null, 1.0 ); } clbk( new Error( 'oops' ) ); } } function y( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { clbk( null, -1.0 ); } } function done( error, result ) { if ( error ) { throw error; } console.log( result ); } trythenAsync( x, y, done ); ``` The function `x` is 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. ```javascript var randu = require( '@stdlib/random/base/randu' ); 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 ); } trythenAsync( x, y, done ); ``` If the error argument is truthy, the function invokes `y`. The number of arguments provided to `y` depends on the function's `length`. If `y` is a unary function, `y` is provided a single argument: - `clbk`: callback to invoke upon function completion Otherwise, `y` is provided two arguments: - `error`: the error from `x` - `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 equal to `null` and all other provided arguments. If the error argument is truthy, the `done` callback is invoked with only the error argument provided by `y`. ```javascript var randu = require( '@stdlib/random/base/randu' ); function x( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { if ( randu() > 0.5 ) { return clbk( null, 1.0, 2.0, 3.0 ); } clbk( new Error( 'beep' ) ); } } function y( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { if ( randu() > 0.5 ) { return clbk( null, 4.0, 5.0, 6.0 ); } clbk( new Error( 'boop' ) ); } } function done( error, a, b, c ) { if ( error ) { console.error( error.message ); } console.log( a, b, c ); } trythenAsync( x, y, done ); ```
## Notes - 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 trythenAsync = require( '@stdlib/utils/async/try-then' ); var i; function next() { trythenAsync( x, y, done ); } function x( clbk ) { setTimeout( onTimeout, 0 ); function onTimeout() { if ( randu() > 0.9 ) { return clbk( null, repeatString( 'BOOP', ceil( randu()*3.0 ) ) ); } clbk( new Error( 'oops' ) ); } } 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(); ```