time-to-botec

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

README.md (9268B)


      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 # mapKeysAsync
     22 
     23 > Map keys from one object to a new object having the same values.
     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 mapKeysAsync = require( '@stdlib/utils/async/map-keys' );
     41 ```
     42 
     43 #### mapKeysAsync( obj, \[options,] transform, done )
     44 
     45 Map keys from one `object` to a new `object` having the same values.
     46 
     47 ```javascript
     48 function transform( key, next ) {
     49     setTimeout( onTimeout, 0 );
     50     function onTimeout() {
     51         next( null, key+':beep' );
     52     }
     53 }
     54 
     55 function done( error, out ) {
     56     if ( error ) {
     57         throw error;
     58     }
     59     console.log( out );
     60     // => { 'a:beep': 1, 'b:beep': 2 }
     61 }
     62 
     63 var obj = {
     64     'a': 1,
     65     'b': 2
     66 };
     67 
     68 mapKeysAsync( obj, transform, done );
     69 ```
     70 
     71 The `next` callback accepts two arguments: `error` and `key`. The second argument to the `next` callback is the transformed property name. If a `transform` function calls the `next` callback with a truthy error argument, the function stops processing any additional own properties and calls the `done` callback for error processing.
     72 
     73 ```javascript
     74 function transform( key, value, next ) {
     75     setTimeout( onTimeout, value );
     76     function onTimeout() {
     77         if ( value === 1 ) {
     78             return next( new Error( 'boop' ) );
     79         }
     80         next( null, key+':beep' );
     81     }
     82 }
     83 
     84 function done( error ) {
     85     if ( error ) {
     86         console.error( error.message );
     87         // => 'boop'
     88     }
     89 }
     90 
     91 var obj = {
     92     'a': 1,
     93     'b': 2
     94 };
     95 
     96 mapKeysAsync( obj, transform, done );
     97 ```
     98 
     99 The function accepts the following `options`:
    100 
    101 -   `limit`: the maximum number of pending invocations at any one time. Default: `infinity`.
    102 -   `series`: `boolean` indicating whether to sequentially invoke the `transform` function for each own property. If `true`, the function sets `options.limit=1`. Default: `false`.
    103 -   `thisArg`: the execution context for `fcn`.
    104 
    105 By default, all properties are processed concurrently, which means that the function does **not** guarantee completion order. To process each property sequentially, set the `series` option to `true`.
    106 
    107 ```javascript
    108 function transform( key, value, next ) {
    109     setTimeout( onTimeout, value );
    110     function onTimeout() {
    111         next( null, key+':beep' );
    112     }
    113 }
    114 
    115 function done( error, out ) {
    116     if ( error ) {
    117         throw error;
    118     }
    119     console.log( out );
    120     // => { 'a:beep': 1, 'b:beep': 2 }
    121 }
    122 
    123 var obj = {
    124     'a': 1,
    125     'b': 2
    126 };
    127 
    128 var opts = {
    129     'series': true
    130 };
    131 
    132 mapKeysAsync( obj, opts, transform, done );
    133 ```
    134 
    135 To limit the maximum number of pending function invocations, set the `limit` option.
    136 
    137 ```javascript
    138 function transform( key, value, next ) {
    139     setTimeout( onTimeout, value );
    140     function onTimeout() {
    141         next( null, key+':beep' );
    142     }
    143 }
    144 
    145 function done( error, out ) {
    146     if ( error ) {
    147         throw error;
    148     }
    149     console.log( out );
    150     // => { 'a:beep': 1, 'b:beep': 2, 'c:beep': 3 }
    151 }
    152 
    153 var obj = {
    154     'a': 1,
    155     'b': 2,
    156     'c': 3
    157 };
    158 
    159 var opts = {
    160     'limit': 2
    161 };
    162 
    163 mapKeysAsync( obj, opts, transform, done );
    164 ```
    165 
    166 To set the execution context of the `transform` function, set the `thisArg` option.
    167 
    168 ```javascript
    169 function transform( key, value, next ) {
    170     this.count += 1;
    171     setTimeout( onTimeout, value );
    172     function onTimeout() {
    173         next( null, key+':beep' );
    174     }
    175 }
    176 
    177 var obj = {
    178     'a': 1,
    179     'b': 2,
    180     'c': 3
    181 };
    182 
    183 var context = {
    184     'count': 0
    185 };
    186 
    187 var opts = {
    188     'thisArg': context
    189 };
    190 
    191 mapKeysAsync( obj, opts, transform, done );
    192 
    193 function done( error, out ) {
    194     if ( error ) {
    195         throw error;
    196     }
    197     console.log( out );
    198     // => { 'a:beep': 1, 'b:beep': 2, 'c:beep': 3 }
    199 
    200     console.log( context.count );
    201     // => 3
    202 }
    203 ```
    204 
    205 When invoked, the `transform` function is provided a maximum of four arguments:
    206 
    207 -   `key`: object key.
    208 -   `value`: object value corresponding to `key`.
    209 -   `obj`: source object.
    210 -   `next`: a callback which should be called once the `transform` function has finished processing a property.
    211 
    212 The actual number of provided arguments depends on function `length`. If the `transform` function accepts two arguments, the `transform` function is provided `key` and `next`. If the `transform` function accepts three arguments, the `transform` function is provided `key`, `value`, and `next`. For every other `transform` function signature, the `transform` function is provided all four arguments.
    213 
    214 ```javascript
    215 function transform( key, value, obj, next ) {
    216     console.log( 'obj: %s. %s: %d', JSON.stringify( obj ), key, value );
    217     setTimeout( onTimeout, value );
    218     function onTimeout() {
    219         next( null, key+':'+value );
    220     }
    221 }
    222 
    223 function done( error, out ) {
    224     if ( error ) {
    225         throw error;
    226     }
    227     console.log( out );
    228 }
    229 
    230 var obj = {
    231     'a': 1,
    232     'b': 2
    233 };
    234 
    235 mapKeysAsync( obj, transform, done );
    236 /* => e.g.,
    237     obj: {"a": 1, "b": 2}. a: 1
    238     obj: {"a": 1, "b": 2}. b: 2
    239     { 'a:1': 1, 'b:2': 2 }
    240 */
    241 ```
    242 
    243 #### mapKeysAsync.factory( \[options,] transform )
    244 
    245 Returns a `function` which invokes a `transform` function once for each own property.
    246 
    247 ```javascript
    248 function transform( key, value, next ) {
    249     setTimeout( onTimeout, value );
    250     function onTimeout() {
    251         next( null, key+':beep' );
    252     }
    253 }
    254 
    255 function done( error, out ) {
    256     if ( error ) {
    257         throw error;
    258     }
    259     console.log( out );
    260 }
    261 
    262 var f = mapKeysAsync.factory( transform );
    263 
    264 var obj1 = {
    265     'a': 1,
    266     'b': 2
    267 };
    268 
    269 f( obj1, done );
    270 // => { 'a:beep': 1, 'b:beep': 2 }
    271 
    272 var obj2 = {
    273     'c': 3,
    274     'd': 4
    275 };
    276 
    277 f( obj2, done );
    278 // => { 'c:beep': 3, 'd:beep': 4 }
    279 ```
    280 
    281 The function accepts the same `options` as `mapKeysAsync()`.
    282 
    283 </section>
    284 
    285 <!-- /.usage -->
    286 
    287 <!-- Package usage notes. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    288 
    289 <section class="notes">
    290 
    291 ## Notes
    292 
    293 -   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.
    294 -   If provided an empty `object`, the function calls the `done` callback with an empty `object`.
    295 -   Key iteration order is **not** guaranteed, as `object` key enumeration is not specified according to the [ECMAScript specification][ecma-262]. In practice, however, most engines use insertion order to sort an `object`'s keys, thus allowing for iteration order.
    296 -   Key insertion order is **not** guaranteed.
    297 -   The value returned by a `transform` function should be a value which can be serialized as an `object` key.
    298 -   The function only maps **own** properties. Hence, the function does **not** map inherited properties.
    299 -   The function **shallow** copies key values.
    300 -   **Neither** `mapKeysAsync` 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`).
    301 
    302 </section>
    303 
    304 <!-- /.notes -->
    305 
    306 <!-- Package usage examples. -->
    307 
    308 <section class="examples">
    309 
    310 ## Examples
    311 
    312 <!-- eslint no-undef: "error" -->
    313 
    314 ```javascript
    315 var resolve = require( 'path' ).resolve;
    316 var readFile = require( '@stdlib/fs/read-file' );
    317 var mapKeysAsync = require( '@stdlib/utils/async/map-keys' );
    318 
    319 var files = {
    320     'file1': resolve( __dirname, 'package.json' ),
    321     'file2': resolve( __dirname, 'README.md' )
    322 };
    323 
    324 function read( key, value, next ) {
    325     var opts = {
    326         'encoding': 'utf8'
    327     };
    328     readFile( value, opts, onFile );
    329 
    330     function onFile( error ) {
    331         if ( error ) {
    332             return next( error, key+':unreadable' );
    333         }
    334         next( null, key+':readable' );
    335     }
    336 }
    337 
    338 function done( error, out ) {
    339     if ( error ) {
    340         throw error;
    341     }
    342     console.log( out );
    343 }
    344 
    345 mapKeysAsync( files, read, done );
    346 ```
    347 
    348 </section>
    349 
    350 <!-- /.examples -->
    351 
    352 <!-- 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. -->
    353 
    354 <section class="references">
    355 
    356 </section>
    357 
    358 <!-- /.references -->
    359 
    360 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    361 
    362 <section class="links">
    363 
    364 [ecma-262]: http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4
    365 
    366 </section>
    367 
    368 <!-- /.links -->