npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

node-each

v1.0.1

Published

Node asynchronous for each that avoids blocking Node Event Loop

Downloads

4,362

Readme

Node Each

semantic-release Travis Codecov npm npm

N(ode) E(each)

If you are doing 'heavy lifting' loops in Node.js you can fork and allocate a new thread. But what if you want to run the loop in the same process and distribute iterations through multiple Event Loop cycles?

Node Each is here to solve the later. It avoids blocking Node.js Event Loop while performing asynchronous and intensive for each loops. It allows to set next iteration to be run on the next Event Loop cycle, giving the opportunity for Node to process queued events.

Install

$ npm install node-each
var ne = require('node-each');

Usage

ne.each(Array, [Callback], [Options])

Array: [*]

Array to run each loop.

Callback: Function(el, i)

  • e{*} - iteration element
  • i{Number} - iteration index

If the callback function returns a Promise back to the iterator handler, the next iteration will only run after Promise fulfilment.

Options: Object{debug, on, when}

  • debug{Boolean} - debug flag (default: false)
  • on{String} - iteration or time (default: iteration)
  • when{Number} - total iteration or total time in milliseconds (decimal allowed) to trigger next cycle (default: 1)

Trigger next Event Loop cycle iteration based 'on' iteration number or time in milliseconds since the last cycle.

By default it will trigger based 'on' iteration every time it reaches 'when', in this case 1. Simply put on every loop iteration.

NE uses process.hrtime() to calculate time, so decimals can be used to work with smaller units.

Returns: Promise{fulfilled(debug)}

Debug: Object{average, cycles, duration, iterations, on, when}

  • average{Number} - average iteration time (ms)
  • cycles{Number} - each total cycles
  • duration{Number} - each duration time (ms)
  • iterations{Number} - each iterations
  • on{String} - each on setting
  • when{String} - each when setting

ne.stats

Object{executing}: Number

  • executing{Number} - number of each loops running at this moment

Examples

var ne = require('node-each');

var names = ['Helen', 'John', 'Peter', 'Jim'];

On: Iteration

var options = {
    debug: true
};

ne.each(names, function(el, i){

    console.log('Name', el + ' has index of ' + i);
  
}, options).then(function(debug) {

    console.log('Finished', debug);
  
});

// Output
// Name Helen has index of 0 - Event Loop Cycle 1
// Name John has index of 1 - Event Loop Cycle 2
// Name Peter has index of 2 - Event Loop Cycle 3
// Name Jim has index of 3 - Event Loop Cycle 4
// Finished {
//    average: 1.58539575,
//    cycles: 4,
//    duration: 6.341583,
//    iterations: 4,
//    on: 'iteration',
//    when: 1
// }

On: Time

var options = {
    debug: true,
    on: 'time',
    when: 150.000001 // equals to 150000001 nanoseconds
};

/** Simulate asynchronous loop operation */
ne.each(names, function(el, i){

    return new Promise(function(resolve) {
    
        setTimeout(function(){

            console.log('Name', el + ' has index of ' + i);
            console.log('Loops executing', ne.stats.executing);
          
            resolve();
          
        }, 100);
      
    });
  
}, options).then(function(debug) {

    console.log('Finished', debug);
    console.log('Loops executing', ne.stats.executing);
  
});

// Output
// Name Helen has index of 0 - Event Loop Cycle 1
// Loops executing 1
// Name John has index of 1 - Event Loop Cycle 1
// Loops executing 1
// Name Peter has index of 2 - Event Loop Cycle 2
// Loops executing 1
// Name Jim has index of 3 - Event Loop Cycle 2
// Loops executing 1
// Finished { 
//    average: 105.3162665,
//    cycles: 2,
//    duration: 421.265066,
//    iterations: 4,
//    on: 'time',
//    when: 150
// }
// Loops executing 0

Dependency

Bluebird

Contribute

Node Each module uses semantic-release with Commit Guidelines.

$ mkdir node-each && cd node-each
$ git clone [email protected]:goncaloneves/node-each.git .
$ npm install
 
$ npm test # Tests with Coverage
$ npm run commit # Commit
$ gulp # Gulp Watch [Eslint, Test]
$ gulp lint # Gulp Eslint
$ gulp test # Gulp Tests

License

MIT License 2015 © Gonçalo Neves