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 🙏

© 2026 – Pkg Stats / Ryan Hefner

oa-ascync

v1.1.0

Published

Async utils for nodejs

Readme

oa-ascync

Build Status Coverage Status

This library is an helper to avoid the Javascript Callback Hell. This project is insprired on https://github.com/caolan/async.

Each function has this interface:

function(err, result) { /* */ }

This permits to connect better all functions present in this library.

This library has is splitted in 4 submodules.

  • parallel: continue on error (goon)
  • parallel: stop on error (stoponerror)
  • serie: do it in serie
  • other: a collection of other functions

The first three submodules have 3 similar function:

  • map
  • parallel/series
  • filter

Common

The difference among the submodules is how the process is done and what happens when an error occurred. In particular:

  • goon: the process is done in parallel and when an error occurred, the process goes on. The final callback has an array/object of error or null as the first parameter and the result accumuled as the second.
  • stoponerror: the process is done in parallel and when an error occurred the process is stopped. The final callback has the error or null as the first parameter and the result as the second.
  • serie: the process is done in serie. All tasks is executed one after the other waiting the next function call. If an error occurred the process is stopped. The final callback is called with the error or null as first parameter and the result accumuled as the second.

map

This function accept an array or object and a iterator function and a callback.

  • iterator is a function long 2. The first parameter is the element/value of the array/object. The second is a next function long 2 that accepts an error or null and the mapped value.
  • callback is a function long 2. The first parameter is an array/object with all errors or null. The second one is the results finished successfully.

This applies the iterator on all elements/values and call callback in the end. The results is an array/object with all mapped values.

var elements = {a: 1, b: 2, c: 3};
function power(el, next) {
  next(null, el * el);
}
// "goon" can be replaced with "stoponerror" or "serie" without any changes
async.goon.map(elements, power, function(err, results) {
  assert.deepEqual({a: 1, b: 4, c: 9}, results);
});
var elements = [1, 2, 3];
function power(el, next) {
  next(null, el * el);
}
// "goon" can be replaced with "stoponerror" or "serie" without any changes
async.goon.map(elements, power, function(err, results) {
  assert.deepEqual([1, 4, 9], results);
});

parallel/series

This function accepts an array/object of functions and a callback.

  • array/object of functions long 1. This paramater is a next function that accepts an optional error and the result.
  • the callback is a function long 2. The first parameter is an array/object of error or null. The second is an array/object with all results finished successfully.

This function calls each function and, in the end, the given callback invoked with the error/errors and the results of all functions.

function giveMeANumber(next) {
  next(null, 1);
}
function giveMeAnotherNumber(next) {
  next(null, 2);
}
function giveMeAString(next) {
  next(null, "A string");
}
// "goon" can be replaced with "stoponerror" or "serie" without any changes
async.goon.parallel({
  giveMeANumber: giveMeANumber,
  giveMeAnotherNumber: giveMeAnotherNumber,
  giveMeAString: giveMeAString,
}, function(err, results) {
  assert.deepEqual({
    giveMeANumber: 1,
    giveMeAnotherNumber: 2,
    giveMeAString: "A string",
  }, results);
});
function giveMeANumber(next) {
  next(null, 1);
}
function giveMeAnotherNumber(next) {
  next(null, 2);
}
function giveMeAString(next) {
  next(null, "A string");
}
// "goon" can be replaced with "stoponerror" or "serie" without any changes
async.goon.parallel([giveMeANumber, giveMeAnotherNumber, giveMeAString], function(err, results) {
  assert.deepEqual([1, 2, "A string"], results);
});

filter

This accept an array or object and a filter function and a callback.

  • filter is a function long 2. The first parameter is the element/value of the array/object. The second is the callback should be called when the filter is done. The second parameter must be a boolean. All not-true values are considered false.
  • callback is a function long 2. The first parameter is an array/object with all errors or null. The second one is the results finished successfully.

This function applies all elements/values to the filter.

var elements = {a: 1, b: 2, c: 3};
function even(el, next) {
  next(null, el % 2 === 0);
}
async.goon.filter(elements, even, function(err, results) {
  assert.deepEqual({b: 2}, results);
});
var elements = [1, 2, 3];
function even(el, next) {
  next(null, el % 2 === 0);
}
async.goon.filter(elements, even, function(err, results) {
  assert.deepEqual([2], results);
});

Other

This module has 3 functions

waterfall

This function accepts an array of functions that are execute one after the other passing the result of previous function to the next.

The first function of the array/object has only one argument: a next function that should be invoked with an error or the result. The other functions have the previous result as first parameter and the next function as second parameter.

If an error occured, the concatenation is stopped and the final callback is called with the error.

var tasks = [
  function(next) {
    next(null, 1)
  },
  function duplicate(n, next) {
    next(null, n * 2)
  },
  function triplicte(n, next) {
    next(null, n * 3)
  },
  function power(n, next) {
    next(null, n * n)
  },
];
async.other.waterfall(tasks, function(err, results) {
  assert.deepEqual(36, results);
});

cascade

This function resolves the dependencies. An example explains better than words.

var tasks = {
  func1: function(next) {
    setTimeout(function() { next(null, 1); }, 10);
  },
  func2: function(next) {
    setTimeout(function() { next(null, 2); }, 10);
  },
  funcSum: ['func1', 'func2', function(prev, next) {
    setTimeout(function() { next(null, prev.func1 + prev.func2); }, 10);
  }],
  funcMultiple: ['func1', 'func2', function(prev, next) {
    setTimeout(function() { next(null, prev.func1 * prev.func2); }, 10);
  }],
  funcRes: ['funcSum', 'funcMultiple', function(prev, next) {
    setTimeout(function() { next(null, {sum: prev.funcSum, molt: prev.funcMultiple}); }, 10);
  }],
};
async.other.cascade(tasks, function(err, results) {
  assert.deepEqual({func1: 1, func2: 2, funcSum: 3, funcMultiple: 2, funcRes: {sum: 3, molt: 2}}, results);
});

solveDependenciesTree

This function resolve a given dependecies tree. The tree is an object that describe the dependecies. This function is different from cascade: the value are object that describes better the dependencies and all tasks have 2 parameters.

If the tree is unsolvable, an object with key __internal__ is passed as error on final callback.

var tree = {
  func1: {
    dependecies: [],
    task: function(prev, next) {
      setTimeout(function() { next(null, 1); }, 10);
    },
  },
  func2: {
    dependecies: [],
    task: function(prev, next) {
      setTimeout(function() { next(null, 2); }, 10);
    },
  },
  funcSum: {
    dependecies: ['func1', 'func2'],
    task: function(prev, next) {
      setTimeout(function() { next(null, prev.func1 + prev.func2); }, 10);
    },
  },
  funcMultiple: {
    dependecies: ['func1', 'func2'],
    task: function(prev, next) {
      setTimeout(function() { next(null, prev.func1 * prev.func2); }, 10);
    },
  },
  funcRes: {
    dependecies: ['funcSum', 'funcMultiple'],
    task: function(prev, next) {
      setTimeout(function() { next(null, {sum: prev.funcSum, molt: prev.funcMultiple}); }, 10);
    },
  },
};
async.other.solveDependenciesTree(tree, function(err, results) {
  assert.deepEqual({func1: 1, func2: 2, funcSum: 3, funcMultiple: 2, funcRes: {sum: 3, molt: 2}}, results);
});

Helper

There're some util functions used in this library and are also exposed.

getObjectValues

var values = async.helper.getObjectValues({a: 1, b: 2});
assert.equal([1, 2], values);

hasOnlyEmptyValues

assert.equal(true, async.helper.hasOnlyEmptyValues({a: false, b: null, c: undefined}));
assert.equal(false, async.helper.hasOnlyEmptyValues({a: false, b: null, c: true}));
assert.equal(false, async.helper.hasOnlyEmptyValues({a: false, b: null, c: {w: true}}));
assert.equal(false, async.helper.hasOnlyEmptyValues({a: [false], b: null, c: undefined}));

getFirstNotNullElement

assert.equal(1, async.helper.getFirstNotNullElement([1, false]));
assert.equal(1, async.helper.getFirstNotNullElement([null, 1, false]));
assert.equal(false, async.helper.getFirstNotNullElement([false, 3]));