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

async-ext

v0.4.0

Published

Extensions to the Node.js async library

Downloads

273

Readme

async-ext

This module consists of a set of functions to extend the capabilities of the Node.js async library.

Installation

npm install async
npm install async-ext

Usage

The easiest way to use async-ext is to extend the async object with the new functions. Here's how you might do it with Underscore:

_ = require 'underscore'
async = _.extend require('async'), require('async-ext')

Functions

async.lift(fun)

"Lifts" a regular old synchronous function into the wondrous world of async.

Why would you ever want to make more functions async then you have to? Well, imagine you were using async.waterfall to get fetch some data asynchronously, transform it synchronously, and send it off somewhere else asynchronously. Your code might look like this:

async.waterfall [
    fetchData
    (data, cb) ->
        try 
            data = transform data
            sendData data, cb
        catch err
            setImmediate -> cb err
], errHandler

With async.lift, you can write that like this:

async.waterfall [
    fetchData
    async.lift (data) -> transform data
    sendData
], errHandler

async.lift takes a synchronous function and returns an asynchronous version of that function that applies its callback to any results returned by the original function.

The input function may accept any number of arguments - the resulting function will as well. If the input function returns a single value, the callback will be called with that value. If the input function returns an array, the callback will be applied to the array.

Any errors thrown by the input function will be caught and passed to the callback. If no error is thrown, the callback will be called with null as the error argument.

The resulting function will call its callback using setImmediate, to prevent releasing the Zalgo.

async.tap(fun)

Lifts a synchronous function but ignores its return value, instead passing along whatever arguments it receives. This can be useful for inserting functions into pipelines when you only care about their side effects.

For example, we can insert some logging statements into our previous waterfall without having to modify any of the preexisting code:

async.waterfall [
    fetchData
    async.lift (data) -> transform data
    async.tap (data) -> console.log 'got some data', data
    sendData # is called with the same data as the logging function
    async.tap -> console.log 'done sending!'
], errHandler

Any errors thrown by the input function will be caught and passed to the callback. If no error is thrown, the callback will be called with null as the error argument.

async.once(fun)

Like _.once, takes an asynchronous function and returns a version of the function that will only run once. Subsequent calls to the function will call the given callback with the same results that were passed to the callback of the first invocation.

If the function is called multiple times, the callbacks will be called in the order of the invocations.

init_db = async.once(db.connect)
init_db (err, conn1) ->
    console.log 'inited 1'
    init_db (err, conn2) ->
        console.log 'inited 2'
)
init_db (err, connr3) ->
    console.log 'inited 3'
# logs 1, 3, 2
# conn1 is conn2 is conn3

async.withTimeout(timeout, fun)

Takes a timeout (in milliseconds) and an asynchronous function and returns a version of the function that will error if the function doesn't finish computation before the timeout elapses.

health_check = (db, cb) ->
    ping = async.withTimeout 2000, db.ping
    ping cb
health_check db, (err) ->
    console.error err
# Assuming the db doesn't respond to the ping within 2 seconds...
# logs "[Error: A function wrapped with async.withTimeout timed out after 2000ms]"

async.if(condition, then_fn, else_fn, cb)

Takes a condition, two functions, and a callback. If the condition evaluates to true, then_fn will be called, else else_fn will be. Both will be given cb as a callback. This allows you to define the callback at the same time as the functions, improving readability.

# without async.if
cb = (output) -> console.log output
if val > 10
  then_fn val, cb
else
  else_fn val, cb
# with async.if
async.if val > 10,
  (cb) -> then_fn(val, cb),
  (cb) -> else_fn(val, cb),
  (output) -> console.log output

async.mapValues(obj, fun, cb)

Takes an object, an async function, and a final callback. async.mapValues creates a new object whose values are the results of applying the function to each key/value pair of the original object. The resulting object is passed to the final callback.

If the function calls its callback with an error, it will short-circuit the computation and pass the error to the final callback.

photo_obj = { file1: 'some-file.txt', file2: 'another-file.txt' }
async.mapValues photo_obj, fs.readFile, (err, res) ->
    console.log res # { file: <some-file data>, file2: <another-file data> }