time-to-botec

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

README.md (9221B)


      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 # mapValuesAsync
     22 
     23 > Map values from one object to a new object having the same keys.
     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 mapValuesAsync = require( '@stdlib/utils/async/map-values' );
     41 ```
     42 
     43 #### mapValuesAsync( obj, \[options,] transform, done )
     44 
     45 Map values from one `object` to a new `object` having the same keys.
     46 
     47 ```javascript
     48 function transform( value, next ) {
     49     setTimeout( onTimeout, value );
     50     function onTimeout() {
     51         next( null, value*2 );
     52     }
     53 }
     54 
     55 function done( error, out ) {
     56     if ( error ) {
     57         throw error;
     58     }
     59     console.log( out );
     60     // => { 'a': 2, 'b': 4 }
     61 }
     62 
     63 var obj = {
     64     'a': 1,
     65     'b': 2
     66 };
     67 
     68 mapValuesAsync( obj, transform, done );
     69 ```
     70 
     71 The `next` callback accepts two arguments: `error` and `value`. The second argument to the `next` callback is the transformed property value. 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( value, key, next ) {
     75     setTimeout( onTimeout, value );
     76     function onTimeout() {
     77         if ( key === 'a' ) {
     78             return next( new Error( 'beep' ) );
     79         }
     80         next( null, value );
     81     }
     82 }
     83 
     84 function done( error ) {
     85     if ( error ) {
     86         console.error( error.message );
     87         // => 'beep'
     88     }
     89 }
     90 
     91 var obj = {
     92     'a': 1,
     93     'b': 2
     94 };
     95 
     96 mapValuesAsync( 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( value, next ) {
    109     setTimeout( onTimeout, value );
    110     function onTimeout() {
    111         next( null, 'beep:'+value );
    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 mapValuesAsync( 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( value, next ) {
    139     setTimeout( onTimeout, value );
    140     function onTimeout() {
    141         next( null, 'beep:'+value );
    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 mapValuesAsync( 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( value, next ) {
    170     this.count += 1;
    171     setTimeout( onTimeout, value );
    172     function onTimeout() {
    173         next( null, 'beep:'+value );
    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 mapValuesAsync( 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 -   `value`: object value corresponding to `key`.
    208 -   `key`: object key.
    209 -   `obj`: source object.
    210 -   `next`: a callback which should be called once the `transform` function has finished processing a property `value`.
    211 
    212 The actual number of provided arguments depends on function `length`. If the `transform` function accepts two arguments, the `transform` function is provided `value` and `next`. If the `transform` function accepts three arguments, the `transform` function is provided `value`, `key`, and `next`. For every other `transform` function signature, the `transform` function is provided all four arguments.
    213 
    214 ```javascript
    215 function transform( value, key, 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 mapValuesAsync( obj, transform, done );
    236 /* => e.g.,
    237     obj: {"a": 1, "b": 2}. a: 1
    238     obj: {"a": 1, "b": 2}. b: 2
    239     { 'a': 'a:1', 'b': 'b:2' }
    240 */
    241 ```
    242 
    243 #### mapValuesAsync.factory( \[options,] transform )
    244 
    245 Returns a `function` which invokes a `transform` function once for each own property.
    246 
    247 ```javascript
    248 function transform( value, next ) {
    249     setTimeout( onTimeout, value );
    250     function onTimeout() {
    251         next( null, 'beep:'+value );
    252     }
    253 }
    254 
    255 function done( error, out ) {
    256     if ( error ) {
    257         throw error;
    258     }
    259     console.log( out );
    260 }
    261 
    262 var f = mapValuesAsync.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 `mapValuesAsync()`.
    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-for-in]. 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 function only maps values assigned to **own** properties. Hence, the function does **not** map values for inherited properties.
    298 -   The function **shallow** copies key values.
    299 -   **Neither** `mapValuesAsync` 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`).
    300 
    301 </section>
    302 
    303 <!-- /.notes -->
    304 
    305 <!-- Package usage examples. -->
    306 
    307 <section class="examples">
    308 
    309 ## Examples
    310 
    311 <!-- eslint no-undef: "error" -->
    312 
    313 ```javascript
    314 var resolve = require( 'path' ).resolve;
    315 var stats = require( 'fs' ).stat;
    316 var mapValuesAsync = require( '@stdlib/utils/async/map-values' );
    317 
    318 var files = {
    319     'file1': resolve( __dirname, 'package.json' ),
    320     'file2': resolve( __dirname, 'README.md' )
    321 };
    322 
    323 function done( error, out ) {
    324     if ( error ) {
    325         throw error;
    326     }
    327     console.log( out );
    328 }
    329 
    330 function getStats( file, next ) {
    331     stats( file, onStats );
    332 
    333     function onStats( error, data ) {
    334         if ( error ) {
    335             error = new Error( 'unable to retrieve stats: '+file );
    336             return next( error );
    337         }
    338         next( null, data );
    339     }
    340 }
    341 
    342 mapValuesAsync( files, getStats, done );
    343 ```
    344 
    345 </section>
    346 
    347 <!-- /.examples -->
    348 
    349 <!-- 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. -->
    350 
    351 <section class="references">
    352 
    353 </section>
    354 
    355 <!-- /.references -->
    356 
    357 <!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
    358 
    359 <section class="links">
    360 
    361 [ecma-262-for-in]: http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4
    362 
    363 </section>
    364 
    365 <!-- /.links -->