time-to-botec

Benchmark sampling in different programming languages
Log | Files | Refs | README

README.md (8208B)


      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 # forEachRightAsync
     22 
     23 > Invoke a function once for each element in a collection, iterating from right to left.
     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 forEachRightAsync = require( '@stdlib/utils/async/for-each-right' );
     41 ```
     42 
     43 #### forEachRightAsync( collection, \[options,] fcn, done )
     44 
     45 Invokes a function once for each element in a `collection`, iterating from right to left.
     46 
     47 ```javascript
     48 function onDuration( value, next ) {
     49     setTimeout( onTimeout, value );
     50     function onTimeout() {
     51         console.log( value );
     52         next();
     53     }
     54 }
     55 
     56 function done( error ) {
     57     if ( error ) {
     58         throw error;
     59     }
     60 }
     61 
     62 var arr = [ 1000, 2500, 3000 ];
     63 
     64 forEachRightAsync( arr, onDuration, done );
     65 /* =>
     66     1000
     67     2500
     68     3000
     69 */
     70 ```
     71 
     72 The function accepts the following `options`:
     73 
     74 -   `limit`: the maximum number of pending invocations at any one time. Default: `infinity`.
     75 -   `series`: `boolean` indicating whether to sequentially invoke `fcn` for each `collection` element. If `true`, the function sets `options.limit=1`. Default: `false`.
     76 -   `thisArg`: the execution context for `fcn`.
     77 
     78 By default, all elements are processed concurrently, which means that the function does **not** guarantee completion order. To process each `collection` element sequentially, set the `series` option to `true`.
     79 
     80 ```javascript
     81 function onDuration( value, next ) {
     82     setTimeout( onTimeout, value );
     83     function onTimeout() {
     84         console.log( value );
     85         next();
     86     }
     87 }
     88 
     89 function done( error ) {
     90     if ( error ) {
     91         throw error;
     92     }
     93 }
     94 
     95 var arr = [ 1000, 2500, 3000 ];
     96 
     97 var opts = {
     98     'series': true
     99 };
    100 
    101 forEachRightAsync( arr, opts, onDuration, done );
    102 /* =>
    103     3000
    104     2500
    105     1000
    106 */
    107 ```
    108 
    109 To limit the maximum number of pending function invocations, set the `limit` option.
    110 
    111 ```javascript
    112 function onDuration( value, next ) {
    113     setTimeout( onTimeout, value );
    114     function onTimeout() {
    115         console.log( value );
    116         next();
    117     }
    118 }
    119 
    120 function done( error ) {
    121     if ( error ) {
    122         throw error;
    123     }
    124 }
    125 
    126 var arr = [ 1000, 2500, 3000 ];
    127 
    128 var opts = {
    129     'limit': 2
    130 };
    131 
    132 forEachRightAsync( arr, opts, onDuration, done );
    133 /* =>
    134     2500
    135     3000
    136     1000
    137 */
    138 ```
    139 
    140 To set the execution context of `fcn`, set the `thisArg` option.
    141 
    142 ```javascript
    143 function onDuration( value, next ) {
    144     this.count += 1;
    145     setTimeout( onTimeout, value );
    146     function onTimeout() {
    147         next();
    148     }
    149 }
    150 
    151 var arr = [ 1000, 2500, 3000 ];
    152 
    153 var context = {
    154     'count': 0
    155 };
    156 
    157 var opts = {
    158     'thisArg': context
    159 };
    160 
    161 forEachRightAsync( arr, opts, onDuration, done );
    162 
    163 function done( error ) {
    164     if ( error ) {
    165         throw error;
    166     }
    167     console.log( context.count );
    168     // => 3
    169 }
    170 ```
    171 
    172 When invoked, `fcn` is provided a maximum of four arguments:
    173 
    174 -   `value`: collection value.
    175 -   `index`: collection index.
    176 -   `collection`: the input `collection`.
    177 -   `next`: a callback which should be called once `fcn` has finished processing a collection `value`.
    178 
    179 The actual number of provided arguments depends on function `length`. If `fcn` accepts two arguments, `fcn` is provided `value` and `next`. If `fcn` accepts three arguments, `fcn` is provided `value`, `index`, and `next`. For every other `fcn` signature, `fcn` is provided all four arguments.
    180 
    181 ```javascript
    182 function onDuration( value, i, collection, next ) {
    183     console.log( 'collection: %s. %d: %d', collection.join( ',' ), i, value );
    184     setTimeout( onTimeout, value );
    185     function onTimeout() {
    186         console.log( value );
    187         next();
    188     }
    189 }
    190 
    191 function done( error ) {
    192     if ( error ) {
    193         throw error;
    194     }
    195 }
    196 
    197 var arr = [ 1000, 2500, 3000 ];
    198 
    199 forEachRightAsync( arr, onDuration, done );
    200 /* =>
    201     collection: 3000,2500,1000. 2: 3000
    202     collection: 3000,2500,1000. 1: 2500
    203     collection: 3000,2500,1000. 0: 1000
    204     1000
    205     2500
    206     3000
    207 */
    208 ```
    209 
    210 #### forEachRightAsync.factory( \[options,] fcn )
    211 
    212 Returns a `function` which invokes a function once for each element in a `collection`, iterating from right to left.
    213 
    214 ```javascript
    215 function onDuration( value, next ) {
    216     setTimeout( onTimeout, value );
    217     function onTimeout() {
    218         console.log( value );
    219         next();
    220     }
    221 }
    222 
    223 function done( error ) {
    224     if ( error ) {
    225         throw error;
    226     }
    227 }
    228 
    229 var f = forEachRightAsync.factory( onDuration );
    230 
    231 var arr1 = [ 1000, 2500, 3000 ];
    232 
    233 f( arr1, done );
    234 /* =>
    235     1000
    236     2500
    237     3000
    238 */
    239 
    240 var arr2 = [ 100, 250, 300 ];
    241 
    242 f( arr2, done );
    243 /* =>
    244     100
    245     250
    246     300
    247 */
    248 ```
    249 
    250 The function accepts the same `options` as `forEachRightAsync()`.
    251 
    252 </section>
    253 
    254 <!-- /.usage -->
    255 
    256 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    257 
    258 <section class="notes">
    259 
    260 ## Notes
    261 
    262 -   A `collection` may be either an [`Array`][mdn-array], [`Typed Array`][mdn-typed-array], or an array-like [`Object`][mdn-object] (excluding `strings` and `functions`).
    263 -   If a provided function calls the `next` callback with a truthy `error` argument, the function suspends execution and immediately calls the `done` callback for subsequent `error` handling.
    264 -   The function does **not** support dynamic `collection` resizing.
    265 -   The function does **not** skip `undefined` elements.
    266 -   **Neither** `forEachRightAsync` nor the function returned by the `factory` method **guarantee** asynchronous execution. 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`).
    267 
    268 </section>
    269 
    270 <!-- /.notes -->
    271 
    272 <!-- Package usage examples. -->
    273 
    274 <section class="examples">
    275 
    276 ## Examples
    277 
    278 <!-- eslint no-undef: "error" -->
    279 
    280 ```javascript
    281 var resolve = require( 'path' ).resolve;
    282 var readFile = require( '@stdlib/fs/read-file' );
    283 var forEachRightAsync = require( '@stdlib/utils/async/for-each-right' );
    284 
    285 var files = [
    286     resolve( __dirname, 'package.json' ),
    287     resolve( __dirname, 'README.md' )
    288 ];
    289 
    290 function done( error ) {
    291     if ( error ) {
    292         throw error;
    293     }
    294     console.log( 'Successfully read all files.' );
    295 }
    296 
    297 function read( file, next ) {
    298     var opts = {
    299         'encoding': 'utf8'
    300     };
    301     readFile( file, opts, onFile );
    302 
    303     function onFile( error ) {
    304         if ( error ) {
    305             error = new Error( 'unable to read file: '+file );
    306             return next( error );
    307         }
    308         console.log( 'Successfully read file: %s', file );
    309         next();
    310     }
    311 }
    312 
    313 forEachRightAsync( files, read, done );
    314 ```
    315 
    316 </section>
    317 
    318 <!-- /.examples -->
    319 
    320 <!-- 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. -->
    321 
    322 <section class="references">
    323 
    324 </section>
    325 
    326 <!-- /.references -->
    327 
    328 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    329 
    330 <section class="links">
    331 
    332 [mdn-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
    333 
    334 [mdn-typed-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray
    335 
    336 [mdn-object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
    337 
    338 </section>
    339 
    340 <!-- /.links -->