README.md (4695B)
1 <!-- 2 3 @license Apache-2.0 4 5 Copyright (c) 2018 The Stdlib Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 19 --> 20 21 # composeAsync 22 23 > [Function composition][function-composition]. 24 25 <!-- Section to include introductory text. Make sure to keep an empty line after the intro `section` element and another before the `/section` close. --> 26 27 <section class="intro"> 28 29 </section> 30 31 <!-- /.intro --> 32 33 <!-- Package usage documentation. --> 34 35 <section class="usage"> 36 37 ## Usage 38 39 ```javascript 40 var composeAsync = require( '@stdlib/utils/async/compose' ); 41 ``` 42 43 #### composeAsync( ...fcn ) 44 45 Returns a composite function. Starting from the right, the composite function evaluates each function and passes the result as the first argument to the next function. The result of the leftmost function is the result of the whole. 46 47 ```javascript 48 function a( x, next ) { 49 setTimeout( onTimeout, 0 ); 50 function onTimeout() { 51 next( null, 2*x ); 52 } 53 } 54 55 function b( x, next ) { 56 setTimeout( onTimeout, 0 ); 57 function onTimeout() { 58 next( null, x+3 ); 59 } 60 } 61 62 function c( x, next ) { 63 setTimeout( onTimeout, 0 ); 64 function onTimeout() { 65 next( null, x/5 ); 66 } 67 } 68 69 var f = composeAsync( c, b, a ); 70 71 function done( error, result ) { 72 if ( error ) { 73 throw error; 74 } 75 console.log( result ); 76 // => 3 77 } 78 79 f( 6, done ); // ((2*x)+3)/5 80 ``` 81 82 The last argument provided to each composed function is a `next` callback which accepts two arguments: 83 84 - `error`: error argument 85 - `result`: function result 86 87 **Only** the rightmost function is explicitly permitted to accept multiple arguments. All other functions are evaluated as **binary** functions. 88 89 ```javascript 90 function a( x, y, next ) { 91 setTimeout( onTimeout, 0 ); 92 function onTimeout() { 93 next( null, (x*5) + (y*3) ); 94 } 95 } 96 97 function b( r, next ) { 98 setTimeout( onTimeout, 0 ); 99 function onTimeout() { 100 next( null, r+12 ); 101 } 102 } 103 104 var f = composeAsync( b, a ); 105 106 function done( error, result ) { 107 if ( error ) { 108 throw error; 109 } 110 console.log( result ); 111 // => 50 112 } 113 114 f( 4, 6, done ); 115 ``` 116 117 </section> 118 119 <!-- /.usage --> 120 121 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 122 123 <section class="notes"> 124 125 ## Notes 126 127 - The function will throw if provided fewer than `2` input arguments. 128 - If a composed function calls the `next` callback with a truthy `error` argument, the function suspends execution and immediately calls the `done` callback for subsequent `error` handling. 129 - 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`). 130 131 </section> 132 133 <!-- /.notes --> 134 135 <!-- Package usage examples. --> 136 137 <section class="examples"> 138 139 ## Examples 140 141 <!-- eslint no-undef: "error" --> 142 143 ```javascript 144 var composeAsync = require( '@stdlib/utils/async/compose' ); 145 146 function a( x, y, next ) { 147 setTimeout( onTimeout, 0 ); 148 function onTimeout() { 149 next( null, x*y ); 150 } 151 } 152 153 function b( z, next ) { 154 setTimeout( onTimeout, 0 ); 155 function onTimeout() { 156 next( null, z+5 ); 157 } 158 } 159 160 function c( r, next ) { 161 setTimeout( onTimeout, 0 ); 162 function onTimeout() { 163 next( null, r/10 ); 164 } 165 } 166 167 var f = composeAsync( c, b, a ); 168 169 function done( error, result ) { 170 if ( error ) { 171 throw error; 172 } 173 console.log( result ); 174 // => 2 175 } 176 177 f( 5, 3, done ); 178 ``` 179 180 </section> 181 182 <!-- /.examples --> 183 184 <!-- Section to include cited references. If references are included, add a horizontal rule *before* the section. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 185 186 <section class="references"> 187 188 </section> 189 190 <!-- /.references --> 191 192 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. --> 193 194 <section class="links"> 195 196 [function-composition]: https://en.wikipedia.org/wiki/Function_composition_%28computer_science%29 197 198 </section> 199 200 <!-- /.links -->