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

alinex-async

v1.0.1

Published

An extended version of the async library.

Downloads

66

Readme

Package: alinex-async

This package is deprecated and will not be developed further. You will find the once... method under util and for the rest use the real async package now in version 2.0.

This package will extend the async module with more useful functions. The package will help in structuring in asynchronous programming.

  • easy functions
  • makes code more readable
  • helps against the callback hell

This is not a complete new module but more an extension to the async library by caolan. I decided to wrap it instead of fork it to let the development of both parts be more independent. So I don't need to update this library to get bugfixes of the core.

The changes to the core async are:

  • added once... methods
  • added mapOf... methods

It is one of the modules of the Alinex Universe following the code standards defined in the General Docs.

Install

NPM Downloads

The easiest way is to let npm add the module directly to your modules (from within you node modules directory):

npm install alinex-async --save

And update it to the latest version later:

npm update alinex-async --save

Always have a look at the latest changes.

Usage

Now it can be used like the normal async module:

async = require 'alinex-async'

Now you may use one of the following methods. All relevant functions are documented whether they belong to this module directly or to the wrapped async class.

Collections

each

Applies the function parallel to each element of array:

async.each [1..5], (v, cb) ->
  # do something with element `v`
  cb()
, (err) ->
  # come here after all elements are processed or one element failed
  # maybe check for errors

It will immediately skip all runs if any one sends an error back and calls the resulting function with the error first occurred.

eachLimit

Also run processing of each element in parallel but limit the maximum parallel runs to prevent overload. If the maximum number of parallel runs is reached the rest will wait till any run finishes.

# set num to the number of parallel runs
async.eachLimit [1..5], num, (v, cb) ->
  # do something with element `v`
  cb()
, (err) ->
  # come here after all elements are processed or one element failed
  # maybe check for errors

eachSeries

The same as above but do each element one after the other.

# set num to the number of parallel runs
async.eachSeries [1..5], (v, cb) ->
  # do something with element `v`
  cb()
, (err) ->
  # come here after all elements are processed or one element failed
  # maybe check for errors

If one run will return an error all further elements won'T be processed.

forEachOf

Like each, except that it iterates over objects, and passes the key as the second argument to the iterator.

async.forEachOf obj, (v, k, cb) ->
  # do something with element `k: v`
  cb()
, (err) ->
  # come here after all elements are processed or one element failed
  # maybe check for errors

It will immediately skip all runs if any one sends an error back and calls the resulting function with the error first occurred.

forEachOfLimit

Also run processing of forEachOf element in parallel but limit the maximum parallel runs to prevent overload. If the maximum number of parallel runs is reached the rest will wait till any run finishes.

# set num to the number of parallel runs
async.forEachOfLimit obj, num, (v, k, cb) ->
  # do something with element `k: v`
  cb()
, (err) ->
  # come here after all elements are processed or one element failed
  # maybe check for errors

forEachOfSeries

The same as above but do forEachOf element one after the other.

# set num to the number of parallel runs
async.forEachOfSeries obj, (v, k, cb) ->
  # do something with element `k: v`
  cb()
, (err) ->
  # come here after all elements are processed or one element failed
  # maybe check for errors

If one run will return an error all further elements won'T be processed.

map

Applies the function parallel to each element of array like each but will return an array of the results:

async.map [1..5], (v, cb) ->
  # do something with element `v`
  cb null, v + 1
, (err, results) ->
  # come here after all elements are processed or one element failed
  # if no failure occurred the results array will have:
  # [2..6] in this example

It will immediately skip all runs if any one sends an error back and calls the resulting function with the error first occurred.

mapLimit

Like with map this will give the same results but only run a maximum of limited parallel calls. If the maximum number of parallel runs is reached the rest will wait till any run finishes.

# set num to the number of parallel runs
async.mapLimit [1..5], num, (v, cb) ->
  # do something with element `v`
  cb null, v + 1
, (err) ->
  # come here after all elements are processed or one element failed
  # if no failure occurred the results array will have:
  # [2..6] in this example

mapSeries

And this method will run all calls each after the other one in series. But also the results array will be the same in the end.

async.mapSeries [1..5], (v, cb) ->
  # do something with element `v`
  cb null, v + 1
, (err) ->
  # come here after all elements are processed or one element failed
  # if no failure occurred the results array will have:
  # [2..6] in this example

mapOf

Like map, except that it iterates over objects, and passes the key as the second argument to the iterator.

obj = {one:1, two:2, three:3}
async.mapOf obj, (v, k, cb) ->
  # do something with element `k: v`
  cb null, v + 1
, (err, result) ->
  # come here after all elements are processed or one element failed
  # if no failure occurred the result object will have:
  # {one:2, two:3, three:4} in this example

It will immediately skip all runs if any one sends an error back and calls the resulting function with the error first occurred.

mapOfLimit

Like with map this will give the same results but only run a maximum of limited parallel calls. If the maximum number of parallel runs is reached the rest will wait till any run finishes.

# set num to the number of parallel runs
obj = {one:1, two:2, three:3}
async.mapOfLimit obj, num, (v, k, cb) ->
  # do something with element `k: v`
  cb null, v + 1
, (err, result) ->
  # come here after all elements are processed or one element failed
  # if no failure occurred the result object will have:
  # {one:2, two:3, three:4} in this example

mapOfSeries

And this method will run all calls each after the other one in series. But also the results array will be the same in the end.

obj = {one:1, two:2, three:3}
async.mapOfSeries obj, (v, k, cb) ->
  # do something with element `k: v`
  cb null, v + 1
, (err, result) ->
  # come here after all elements are processed or one element failed
  # if no failure occurred the result object will have:
  # {one:2, two:3, three:4} in this example

filter

reject

Control flow

series

parallel

parallelLimit

whilst

doWhilst

until

doUntil

forever

waterfall

applyEach

applyEachSeries

queue

priorityQueue

retry

times

timesSeries

Function wrapper

The following functions are used to wrap functions to give them more functionality. You will get a resulting function which can be called any time.

In all of the following methods you may give an optional context to use as first parameter. So to call it from class do so like:

class = Test
  init: async.once this, (cb) ->
    # method...
    cb null, @status

That allows your function to access class members and methods. Keep in mind to use => if you use sub functions.

If you use it in module.exports then do it as follows:

module.exports =
  anyMethod: (cb) ->
  # and so on

module.exports.init = async.once module.exports, (cb) ->
  # method...
  @anyMethod cb

Like you see above you have to declare this method separately so that the async.once method can access the now already defined module.exports object.

once

The second and later calls will return with the same result:

fn = async.once (cb) ->
  time = process.hrtime()
  setTimeout ->
    cb null, time[1]
  , 1000

Use this to make some initializations which only have to run once but neither function may start because it is not done:

async.parallel [ fn, fn ], (err, results) ->
  # same as with `once.atime` it will come here exactly after the
  # first call finished because the second one will get the
  # result the same time
  # results here will be the same integer, twice
  fn (err, result) ->
    # and this call will return imediately with the previous result

onceSkip

A function may be wrapped with the once method:

fn = async.onceSkip (a, b, cb) -> cb null, a + b

And now you can call the function as normal but on the second call it will return imediately without running the code:

fn 2, 3, (err, x) ->
  // x will now be 5
  fn 2, 9, (err, x) ->
    // err will now be set on the second call

You may use this helper in case of initialization (wait) there a specific method have to run once before any other call can succeed. Or then events are involved and an error event will trigger the callback and the end event will do the same.

onceThrow

Throw an error if it is called a second time:

fn = async.onceThrow (a, b, cb) -> cb null, a + b

If you call this method multiple times it will throw an exception:

fn 2, 3, (err, x) ->
  # x will now be 5
  fn 2, 9, (err, x) ->
    # will neither get there because an exception is thrown above

onceTime

Only run it once at a time, queue following requests and send them the result of the next run. All calls get the same result, but then the process is already started it will list the following calls for the next round. This assures that their result is from the newest data set because you may changed something while the first run was already working.

fn = async.onceTime (cb) ->
  time = process.hrtime()
  setTimeout ->
    cb null, time[1]
  , 1000

And now you may call it multiple times but it will not run more than once simultaneously. But all simultaneous calls will get the same result.

async.parallel [ fn, fn ], (err, results) ->
  # will come here exactly after the first call finished (because the
  # second will do so the same time)
  # results here will be the same integer, twice

License

Copyright 2015-2016 Alexander Schilling

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.