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

artillery-async

v1.0.5

Published

Common patterns for asynchronous code

Downloads

2

Readme

ArtilleryAsync

Build Status Coverage Status Issues Dependencies License

Common patterns for writing asynchronous code.

Install using npm install artillery-async

Why ArtilleryAsync instead of Async.js?

  • Async's API is difficult. Async provides 60+ oddly-named functions with overlapping functionality. ArtilleryAsync is six functions and that's all we've needed after writing 100,000+ lines of JavaScript over four years.
  • Async is inconsistent. Sometimes Async calls callbacks synchronously and sometimes it doesn't. ArtilleryAsync does things synchronously when possible. Yes, this means you might overflow the call stack, but ArtilleryAsync provides the choice of when to use process.nextTick() or setImmediate().
  • Async's implementation is unwieldy. We had a lot of difficulty when we tried to debug async. ArtilleryAsync's implementation is only 105 lines of CoffeeScript.

Contents

Functions

async.barrier(count, callback)

  • count Number
  • callback Function(err)

Returns a function that executes callback after being called count times. The returned function takes no arguments. It's like parallel() but makes code simpler, especially when you don't need to keep track of errors.

Example

var async = require('artillery-async');

function loadDependencies(deps, cb) {
  var i, barrier = async.barrier(deps.length, cb);
  for (i = 0; i < deps.length; i++) {
    (function(dep) {
      loadSingleItem(dep, function(err, contents) {
        if (err) console.error(dep + " didn't load: " + err);
        barrier();
      });
    })(deps[i]);
  }
}

async.series(steps, callback)

  • steps Array of Function([args...,] callback)
  • callback Function(err[, args...])

Runs each function in steps serially passing any callback arguments to the next function. When the last step has finished, callback is executed. If any step calls its callback with an error, the final callback is executed immediately with that error and no further steps are run.

This is the most popular function in this module. It's usually used as a control flow mechanism — the cascading arguments aren't used that often but the technique can come in handy.

Example

var async = require('artillery-async');

async.series([
  function(cb) {
    fs.exists(path, cb);
  },
  function(exists, cb) {
    if (exists) fs.readFile(path, cb);
  },
  function(contents, cb) {
    request.post('https://example.com/upload', { form: { file: contents } }, cb);
  },
  function(res, body, cb) {
    cb(null, res.statusCode);
  }
], function(err, code) {
  if (err) {
    console.error('Error:', err);
  } else {
    console.log('Done! Got status code:', code);
  }
});

async.parallel(steps, callback)

  • steps Array of Function(callback)
  • callback Function(err)

Runs each function in steps in parallel. When all steps have finished, callback is executed. Any errors produced by the steps are accumulated and passed to callback as an array.

Example

var async = require('artillery-async');

app.get('/home', function(req, res) {
  var result = {};
  async.parallel([

    function getNews(cb) {
      db.news.getAll({ limit: 10 }, function(err, items) {
        result.news = items;
        cb(err);
      });
    },

    function getGames(cb) {
      db.games.getAll({ limit: 10 }, function(err, items) {
        result.games = items;
        cb(err);
      });
    },

  ], function(err) {
    if (err) {
      res.code(500).send(err);
    } else {
      res.render('home', result);
    }
  });

});

async.while(condition, iterator, callback)

  • condition Function()
  • iterator Function(callback)
  • callback Function(err)

Repeatedly calls iterator while the return value of condition is true or iterator calls its callback with and error. Then callback is called, possibly with an error if iterator produced one.

Example

var async = require('artillery-async');
var i = 0;

function cond() { return i <= 20; }

function iter(cb) {
  db.items.insert({ id: i++ }, cb);
}

async.while(cond, iter, function(err) {
  if (err) {
    console.error('Insert failed:', err);
  } else {
    console.log('Done!');
  }
});

async.forEachSeries(items, iterator, callback)

  • items Array
  • iterator Function(item, callback)
  • callback Function(err)

Calls iterator with each item in items in serial, finally calling callback at the end. If the iterator function calls its callback with an error, no more items are processed and callback is called with the error.

var async = require('artillery-async');

async.forEachSeries(
  filesToRemove,
  function(filename, cb) {
    promptUser('Are you sure you want to delete ' + filename + '?', function(err, choice) {
      if (err) return cb(err);
      if (choice) {
        deleteRecursive(filename, cb);
      } else {
        cb();
      }
    });
  },
  function(err) {
    if (err) {
      showAlert('Error: ' + err);
    }
  }
);

async.forEachParallel(items, iterator, [limit,] callback)

  • items Array
  • iterator Function(item, callback)
  • limit (optional) Number
  • callback Function(err)

Calls iterator with each item in items in parallel and calls callback when complete. If limit is specified, no more than that many iterators will be in flight at any time. Any errors produced by the steps are accumulated and passed to callback as an array.

Example

var async = require('artillery-async');

async.forEachParallel(
  filesToUpload,

  MAX_UPLOAD_CONCURRENCY, // 10 or so

  function(filename, cb) {
    fs.readFile(filename, function(err, contents) {
      if (err) return cb(err);
      s3.putObject({ Key: filename, Body: contents }, cb);
    });
  },

  function(err, code) {
    if (err) {
      console.error('Error:', err);
    } else {
      console.log('Done!');
    }
  }
);

Notes

No mechanisms are provided for controlling the context. If you need the this variable, you'll need to scope it yourself (var that = this;) or use Function.bind().