Async utilities for node and the browser

Overview

Async Logo

Build Status via Travis CI Build Status via Azure Pipelines NPM version Coverage Status Join the chat at https://gitter.im/caolan/async jsDelivr Hits

Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Although originally designed for use with Node.js and installable via npm i async, it can also be used directly in the browser. A ESM/MJS version is included in the main async package that should automatically be used with compatible bundlers such as Webpack and Rollup.

A pure ESM version of Async is available as async-es.

For Documentation, visit https://caolan.github.io/async/

For Async v1.5.x documentation, go HERE

// for use with Node-style callbacks...
var async = require("async");

var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
var configs = {};

async.forEachOf(obj, (value, key, callback) => {
    fs.readFile(__dirname + value, "utf8", (err, data) => {
        if (err) return callback(err);
        try {
            configs[key] = JSON.parse(data);
        } catch (e) {
            return callback(e);
        }
        callback();
    });
}, err => {
    if (err) console.error(err.message);
    // configs is now a map of JSON data
    doSomethingWith(configs);
});
var async = require("async");

// ...or ES2017 async functions
async.mapLimit(urls, 5, async function(url) {
    const response = await fetch(url)
    return response.body
}, (err, results) => {
    if (err) throw err
    // results is now an array of the response bodies
    console.log(results)
})
Comments
  • Modularization

    Modularization

    A work in progress to bring modular support and lodash implementations of certain methods.

    Previous discussion be found here #984.

    Resolves #984

    See https://github.com/caolan/async/tree/modularization/build for the generated bundles


    TODOS

    • [x] script releases:
      • generate modular builds/files
      • copy ES modules to build/es
      • add git commit
      • npm test
      • smoke test build files
      • cd build/
      • publish npm release
      • revert modular build changes, returning async to normal folder structure
      • git tag, git push
    • [x] ~~possibly? create npm release for each module~~
    • [x] https://github.com/caolan/async/pull/984#issuecomment-168450571
    • [x] use baseOrderBy in the implementation of internal/flatten?
    • [x] ~~move documentation to jsdoc format (bonus?)~~ save for later
    • [x] test package with npm pack before first 2.0 publish
    enhancement 
    opened by megawac 65
  • Adding forEachOf to Iterate Objects

    Adding forEachOf to Iterate Objects

    So, I needed the ability to iterate objects (and get the key passed into the iterator) and noticed it was not done because it would break compatibility with the Node.js standard libs. I am proposing this "convention" of adding the Of suffix on iterators that deal with objects. (instead of arrays)

    If this entire concept is rejected outright, then I'll stop here. However, if this seems like a good idea/convention I can finish up adding the same concept to the other various collection iterators.

    Usage:

    async.forEachOf({ a: 1, b: 2 }, function (value, key, callback) {
        // value = 1, 2
        // key   = a, b
    }, function (err) {
        // complete
    });
    
    opened by dominicbarnes 38
  • Support for domains.

    Support for domains.

    This patch adds support for domains to async. The test addition is purely illustrative, i have no idea how to write or run tests the way you've got em and running npm test appears to do nothing.

    The style of support:

    if (process.domain) callback = process.domain.bind(callback)
    

    Is something we discussed and established at NodeConf SummerCamp. The basic premise is that whoever owns an upper level transaction (like a web framework handling an HTTP request) will create a domain and wrap the handlers it fires for that transaction. The developer writing handlers has no idea there is a domain, and it's up to API authors (async, request, node-redis) to make sure they attach to the domain when it is active. In the case of request, it's all in an EventEmitter so it's automatically added, but for node-redis and async and other pure callback based APIs there will need to be code like this that binds the incoming callback to the domain so that any errors thrown in the handler get picked up by the transaction holder's domain.

    I hope that makes sense :)

    opened by mikeal 29
  • Adds support for es6 iterators

    Adds support for es6 iterators

    Still not sure if this is the right take to address this. The main issues is I expect there will be a perf hit as a result of creating a new array ([value, key]) at each step iteration step, instead of just passing keys directly (benchmarks to follow).

    Fixes #839

    Benchmarks

    Comparing v1.3.0 with current on Node v2.3.3
    --------------------------------------
    each(10) v1.3.0 x 36,160 ops/sec ±3.60% (24 runs sampled), 0.0277ms per run
    each(10) current x 35,297 ops/sec ±1.45% (28 runs sampled), 0.0283ms per run
    v1.3.0 is faster
    --------------------------------------
    each(300) v1.3.0 x 6,017 ops/sec ±1.55% (26 runs sampled), 0.166ms per run
    each(300) current x 5,883 ops/sec ±1.06% (28 runs sampled), 0.17ms per run
    v1.3.0 is faster
    --------------------------------------
    each(10000) v1.3.0 x 215 ops/sec ±1.33% (28 runs sampled), 4.64ms per run
    each(10000) current x 207 ops/sec ±3.90% (28 runs sampled), 4.84ms per run
    v1.3.0 is faster
    --------------------------------------
    eachSeries(10) v1.3.0 x 19,552 ops/sec ±1.27% (27 runs sampled), 0.0511ms per run
    eachSeries(10) current x 18,455 ops/sec ±4.19% (26 runs sampled), 0.0542ms per run
    v1.3.0 is faster
    --------------------------------------
    eachSeries(300) v1.3.0 x 1,115 ops/sec ±2.07% (27 runs sampled), 0.897ms per run
    eachSeries(300) current x 1,023 ops/sec ±2.77% (25 runs sampled), 0.978ms per run
    v1.3.0 is faster
    --------------------------------------
    eachSeries(10000) v1.3.0 x 35.27 ops/sec ±1.47% (29 runs sampled), 28.4ms per run
    eachSeries(10000) current x 31.43 ops/sec ±3.30% (27 runs sampled), 31.8ms per run
    v1.3.0 is faster
    --------------------------------------
    eachLimit(10) v1.3.0 x 25,702 ops/sec ±4.46% (28 runs sampled), 0.0389ms per run
    eachLimit(10) current x 25,670 ops/sec ±2.65% (27 runs sampled), 0.039ms per run
    Tie
    --------------------------------------
    eachLimit(300) v1.3.0 x 2,282 ops/sec ±2.68% (28 runs sampled), 0.438ms per run
    eachLimit(300) current x 2,321 ops/sec ±3.81% (25 runs sampled), 0.431ms per run
    Tie
    --------------------------------------
    map(10) v1.3.0 x 32,804 ops/sec ±3.23% (25 runs sampled), 0.0305ms per run
    map(10) current x 32,166 ops/sec ±1.56% (27 runs sampled), 0.0311ms per run
    Tie
    --------------------------------------
    map(300) v1.3.0 x 5,134 ops/sec ±1.12% (28 runs sampled), 0.195ms per run
    map(300) current x 4,830 ops/sec ±2.39% (28 runs sampled), 0.207ms per run
    v1.3.0 is faster
    --------------------------------------
    map(10000) v1.3.0 x 172 ops/sec ±2.41% (28 runs sampled), 5.81ms per run
    map(10000) current x 165 ops/sec ±2.19% (28 runs sampled), 6.07ms per run
    v1.3.0 is faster
    --------------------------------------
    mapSeries(10) v1.3.0 x 17,971 ops/sec ±1.44% (27 runs sampled), 0.0556ms per run
    mapSeries(10) current x 17,425 ops/sec ±2.19% (27 runs sampled), 0.0574ms per run
    v1.3.0 is faster
    --------------------------------------
    mapSeries(300) v1.3.0 x 969 ops/sec ±3.29% (25 runs sampled), 1.03ms per run
    mapSeries(300) current x 962 ops/sec ±2.49% (27 runs sampled), 1.04ms per run
    Tie
    --------------------------------------
    mapSeries(10000) v1.3.0 x 30.75 ops/sec ±4.29% (26 runs sampled), 32.5ms per run
    mapSeries(10000) current x 30.44 ops/sec ±5.64% (26 runs sampled), 32.8ms per run
    Tie
    --------------------------------------
    mapLimit(10) v1.3.0 x 24,858 ops/sec ±1.12% (27 runs sampled), 0.0402ms per run
    mapLimit(10) current x 25,084 ops/sec ±1.20% (28 runs sampled), 0.0399ms per run
    Tie
    
    feature performance 
    opened by megawac 27
  • convert tests to mocha

    convert tests to mocha

    @aearly @megawac

    just a proof of concept where you can run mocha tests in node and in the browser. Works right along side the nodeunit tests, so could be transitioned over one by one.

    opened by charlierudolph 25
  • 2.0.0 ready to go?

    2.0.0 ready to go?

    I think its time. Everything in the milestone is complete, and the docs site is up and running. (except for the during inconsistency issue, which I think is just a docs fix)

    I think 2.0.0 is ready for to be released into the wild!

    cc @megawac

    opened by aearly 22
  • Promise support

    Promise support

    Add promise support to allow mix different tasks:

    async.waterfall([
        function (done) {
            // Do something and call done()
            fs.readFile(filepath, done);
        },
        function(content) {
            // Do something and return Promise
            return mongoose.models.file.create({
                name: filepath,
                content: content
            });
        }
    ], (err) => {
        if (err) {
            console.error(err);
        }
    });
    
    feature 
    opened by rumkin 22
  • suggestion: internally split into separate module files to make optimised builds easier

    suggestion: internally split into separate module files to make optimised builds easier

    I just forked this project specifically so I could use priorityQueue() and virtually nothing else. It occurs to me that this is a long-term mistake because I'll miss out on future improvements to this function unless I manually import them.

    May I suggest splitting async.js into multiple files in a lib sub-directory, to facilitate delivering async's functionality to the browser whilst eschewing unnecessary bytes?

    This may be of little benefit for server-side users, but every byte counts in the front-end.

    Also, whilst undertaking this pruning, it occurred to me that dependencies between internal and exported methods isn't always clear unless you carefully read the source code. Modularising could assist in making these interdependencies more clear.

    What do you think? Should I start a Pull Request for this, or is a bad idea / waste of time?

    feature duplicate 
    opened by jokeyrhyme 22
  • Add someLimit and everyLimit

    Add someLimit and everyLimit

    Merges the implementations of some and every and adds their respective limit functions (with partial short circuiting)

    PS I think short circuiting should be done like lodash does it (allowing each to break): if cb resolves with cb(false) you break the loop (in lodash if you return false it breaks the loop)

    Resolves #548

    opened by megawac 21
  • Fixed nasty callback duplication.

    Fixed nasty callback duplication.

    I had some case where the second error response was called during the callback of the first error response in an async call before the callback could be replaced with a noop. That resulted in the error case where the callback was called twice with an error message. That was pretty hard to debug. I figured that the same error could occur at other places as well and changed it there too. It would be nice if someone could provide unit tests for these changes, else I will provide them as soon as I have time for it.

    bug 
    opened by martinheidegger 19
  • applyEach arguments position

    applyEach arguments position

    Currently the applyEach and applyEachSeries functions have the following type signature:

    async.applyEach(fns, ...args?, callback?)
    

    Having a rest parameter in the middle of the arguments list is very difficult to write a type annotation for. It's currently not possible in either Flow or TypeScript, which is why you see stuff like this (I'm writing a similar type definition for Flow right now).

    Would it be okay to switch the argument order around and make callback nullable so it is like this?

    async.applyEach(fns, callback | null, ...args?)
    

    Or use an array instead of a rest parameter?

    async.applyEach(fns, args?: Array<any>, callback?)
    
    breaking-change feedback-wanted 
    opened by jamiebuilds 18
  • with async.queue order of execution is different when using promises instead of callbacks but should be identical

    with async.queue order of execution is different when using promises instead of callbacks but should be identical

    What version of async are you using?

    3.2.4

    Which environment did the issue occur in (Node/browser/Babel/Typescript version)

    Node

    What did you do? Please include a minimal reproducible case illustrating issue.

    Using async.queue I get different execution results when I use promises instead of callbacks.

    https://stackblitz.com/edit/node-qeye7d?file=index.js

    You can execute the code in this example by typing node index in the stackblitz terminal.

    What did you expect to happen?

    Results should be the same.

    What was the actual result?

    Results were different in terms of order of execution.


    Here's my code:

    const async = require('async');
    
    const myFunc = async () => {
      // CALLBACKS
      console.log();
      console.log('CALLBACKS');
    
      const worker1 = (job, callback) => {
        console.log('job started', job.name);
        setTimeout(() => callback(null, job), 1000);
      };
    
      const q1 = async.queue(worker1, 1);
    
      q1.push({ name: 'job1' }, (err, job) => {
        console.log('job done', job);
      });
      q1.push({ name: 'job2' }, (err, job) => {
        console.log('job done', job);
      });
    
      await q1.drain();
    
      // PROMISES
      console.log();
      console.log('PROMISES');
    
      const worker2 = async (job) => {
        return new Promise((resolve) => {
          console.log('job started', job.name);
          setTimeout(() => resolve(job), 1000);
        });
      };
    
      const q2 = async.queue(worker2, 1);
    
      q2.push({ name: 'job1' }).then((job) => {
        console.log('job done', job);
      });
      q2.push({ name: 'job2' }).then((job) => {
        console.log('job done', job);
      });
    
      await q2.drain();
    };
    
    myFunc();
    

    Actual output is:

    CALLBACKS job started job1 job done { name: 'job1' } job started job2 job done { name: 'job2' }

    PROMISES job started job1 job started job2 job done { name: 'job1' } job done { name: 'job2' }

    Expected output is:

    CALLBACKS job started job1 job done { name: 'job1' } job started job2 job done { name: 'job2' }

    PROMISES job started job1 job done { name: 'job1' } job started job2 job done { name: 'job2' }

    opened by danday74 0
  • Add adaptive functions

    Add adaptive functions

    I think it would be nice to add adaptive parallelism to existing functions or create new ones.

    image https://netflixtechblog.medium.com/performance-under-load-3e6fa9a60581

    For example: There is a maximum, minimum, initial and current limit. There is a callback that accepts an error that occurred during the call (for example, an error related to parallelism or another error) and returns a boolean (whether to reduce the limit or not).

    opened by AlexRMU 0
  • Bump chai from 4.3.6 to 4.3.7

    Bump chai from 4.3.6 to 4.3.7

    Bumps chai from 4.3.6 to 4.3.7.

    Release notes

    Sourced from chai's releases.

    v4.3.7

    What's Changed

    Full Changelog: https://github.com/chaijs/chai/compare/v4.3.6...v4.3.7

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies javascript 
    opened by dependabot[bot] 0
  • Bump yargs from 17.5.1 to 17.6.2

    Bump yargs from 17.5.1 to 17.6.2

    Bumps yargs from 17.5.1 to 17.6.2.

    Changelog

    Sourced from yargs's changelog.

    17.6.2 (2022-11-03)

    Bug Fixes

    • deps: update dependency yargs-parser to v21.1.1 (#2231) (75b4d52)
    • lang: typo in Finnish unknown argument singular form (#2222) (a6dfd0a)

    17.6.1 (2022-11-02)

    Bug Fixes

    • lang: fix "Not enough non-option arguments" message for the Czech language (#2242) (3987b13)

    17.6.0 (2022-10-01)

    Features

    Bug Fixes

    • deno: use 'globalThis' instead of 'window' (#2186) (#2215) (561fc7a)
    • deps: cliui with forced strip-ansi update (#2241) (38e8df1)
    • dont clobber description for multiple option calls (#2171) (f91d9b3)
    • typescript: address warning with objectKeys (394f5f8)
    Commits
    • 2e0ef3c chore(main): release 17.6.2 (#2260)
    • a6dfd0a fix(lang): typo in Finnish unknown argument singular form (#2222)
    • cb02c36 docs: add Typescript example for .terminalWidth() (#2224)
    • a1b2eb7 docs: add Typescript example for .terminalWidth() (#2224)
    • 75b4d52 fix(deps): update dependency yargs-parser to v21.1.1 (#2231)
    • bc84a61 build: GitHub Workflows security hardening (#2238)
    • f727e71 chore(main): release 17.6.1 (#2257)
    • b8c9eda fix(deno): refactor to avoid prompts during module import (#2217)
    • 1deed85 chore(deps): update dependency @​types/node to v18 (#2255)
    • 3987b13 fix(lang): fix "Not enough non-option arguments" message for the Czech langua...
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies javascript 
    opened by dependabot[bot] 0
  • Bump jsdoc from 3.6.11 to 4.0.0

    Bump jsdoc from 3.6.11 to 4.0.0

    Bumps jsdoc from 3.6.11 to 4.0.0.

    Changelog

    Sourced from jsdoc's changelog.

    4.0.0 (November 2022)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies javascript 
    opened by dependabot[bot] 0
  • Bump fs-extra from 10.1.0 to 11.1.0

    Bump fs-extra from 10.1.0 to 11.1.0

    Bumps fs-extra from 10.1.0 to 11.1.0.

    Changelog

    Sourced from fs-extra's changelog.

    11.1.0 / 2022-11-29

    • Re-add main field to package.json for better TypeScript compatibility (#979, #981)

    11.0.0 / 2022-11-28

    Breaking Changes

    • Don't allow requiring fs-extra/lib/SOMETHING (switched to exports) (#974)
    • Require Node v14.14+ (#968, #969)

    New Features

    • Add fs-extra/esm for ESM named export support; see docs for details (#746, #974)
    • Add promise support for fs.readv() (#970)

    Bugfixes

    • Don't stat filtered items in copy* (#965, #971)
    • Remove buggy stats check in copy (#918, #976)
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies javascript 
    opened by dependabot[bot] 0
Releases(v2.3.0)
  • v2.3.0(Apr 6, 2017)

    • Added support for ES2017 async functions. Wherever you can pass a Node-style/CPS function that uses a callback, you can also pass an async function. Previously, you had to wrap async functions with asyncify. The caveat is that it will only work if async functions are supported natively in your environment, transpiled implementations can't be detected. (#1386, #1390)
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Apr 6, 2017)

  • v2.1.5(Apr 6, 2017)

    • Fix auto bug when function names collided with Array.prototype (#1358)
    • Improve some error messages (#1349)
    • Avoid stack overflow case in queue
    • Fixed an issue in some, every and find where processing would continue after the result was determined.
    • Cleanup implementations of some, every and find
    Source code(tar.gz)
    Source code(zip)
  • v2.1.3(Apr 6, 2017)

  • v2.1.2(Apr 6, 2017)

  • v2.1.0(Apr 6, 2017)

  • v2.0.0(Apr 6, 2017)

    Lots of changes here!

    First and foremost, we have a slick new site for docs. Special thanks to @hargasinski for his work converting our old docs to jsdoc format and implementing the new website. Also huge ups to @ivanseidel for designing our new logo. It was a long process for both of these tasks, but I think these changes turned out extraordinary well.

    The biggest feature is modularization. You can now require("async/series") to only require the series function. Every Async library function is available this way. You still can require("async") to require the entire library, like you could do before.

    We also provide Async as a collection of ES2015 modules. You can now import {each} from 'async-es' or import waterfall from 'async-es/waterfall'. If you are using only a few Async functions, and are using a ES bundler such as Rollup, this can significantly lower your build size.

    Major thanks to @Kikobeats, @aearly and @megawac for doing the majority of the modularization work, as well as @jdalton and @Rich-Harris for advisory work on the general modularization strategy.

    Another one of the general themes of the 2.0 release is standardization of what an "async" function is. We are now more strictly following the node-style continuation passing style. That is, an async function is a function that:

    1. Takes a variable number of arguments
    2. The last argument is always a callback
    3. The callback can accept any number of arguments
    4. The first argument passed to the callback will be treated as an error result, if the argument is truthy
    5. Any number of result arguments can be passed after the "error" argument
    6. The callback is called once and exactly once, either on the same tick or later tick of the JavaScript event loop.

    There were several cases where Async accepted some functions that did not strictly have these properties, most notably auto, every, some, and filter.

    Another theme is performance. We have eliminated internal deferrals in all cases where they make sense. For example, in waterfall and auto, there was a setImmediate between each task -- these deferrals have been removed. A setImmediate call can add up to 1ms of delay. This might not seem like a lot, but it can add up if you are using many Async functions in the course of processing a HTTP request, for example. Nearly all asynchronous functions that do I/O already have some sort of deferral built in, so the extra deferral is unnecessary. The trade-off of this change is removing our built-in stack-overflow defense. Many synchronous callback calls in series can quickly overflow the JS call stack. If you do have a function that is sometimes synchronous (calling its callback on the same tick), and are running into stack overflows, wrap it with async.ensureAsync().

    Another big performance win has been re-implementing queue, cargo, and priorityQueue with doubly linked lists instead of arrays. This has lead to queues being an order of magnitude faster on large sets of tasks.

    New Features

    • Async is now modularized. Individual functions can be require()d from the main package. (require('async/auto')) (#984, #996)
    • Async is also available as a collection of ES2015 modules in the new async-es package. (import {forEachSeries} from 'async-es') (#984, #996)
    • Added race, analogous to Promise.race(). It will run an array of async tasks in parallel and will call its callback with the result of the first task to respond. (#568, #1038)
    • Collection methods now accept ES2015 iterators. Maps, Sets, and anything that implements the iterator spec can now be passed directly to each, map, parallel, etc.. (#579, #839, #1074)
    • Added mapValues, for mapping over the properties of an object and returning an object with the same keys. (#1157, #1177)
    • Added timeout, a wrapper for an async function that will make the task time-out after the specified time. (#1007, #1027)
    • Added reflect and reflectAll, analagous to Promise.reflect(), a wrapper for async tasks that always succeeds, by gathering results and errors into an object. (#942, #1012, #1095)
    • constant supports dynamic arguments -- it will now always use its last argument as the callback. (#1016, #1052)
    • setImmediate and nextTick now support arguments to partially apply to the deferred function, like the node-native versions do. (#940, #1053)
    • auto now supports resolving cyclic dependencies using Kahn's algorithm (#1140).
    • Added autoInject, a relative of auto that automatically spreads a task's dependencies as arguments to the task function. (#608, #1055, #1099, #1100)
    • You can now limit the concurrency of auto tasks. (#635, #637)
    • Added retryable, a relative of retry that wraps an async function, making it retry when called. (#1058)
    • retry now supports specifying a function that determines the next time interval, useful for exponential backoff, logging and other retry strategies. (#1161)
    • retry will now pass all of the arguments the task function was resolved with to the callback (#1231).
    • Added q.unsaturated -- callback called when a queue's number of running workers falls below a threshold. (#868, #1030, #1033, #1034)
    • Added q.error -- a callback called whenever a queue task calls its callback with an error. (#1170)
    • applyEach and applyEachSeries now pass results to the final callback. (#1088)

    Breaking changes

    • Calling a callback more than once is considered an error, and an error will be thrown. This had an explicit breaking change in waterfall. If you were relying on this behavior, you should more accurately represent your control flow as an event emitter or stream. (#814, #815, #1048, #1050)
    • auto task functions now always take the callback as the last argument. If a task has dependencies, the results object will be passed as the first argument. To migrate old task functions, wrap them with _.flip (#1036, #1042)
    • Internal setImmediate calls have been refactored away. This may make existing flows vulnerable to stack overflows if you use many synchronous functions in series. Use ensureAsync to work around this. (#696, #704, #1049, #1050)
    • map used to return an object when iterating over an object. map now always returns an array, like in other libraries. The previous object behavior has been split out into mapValues. (#1157, #1177)
    • filter, reject, some, every, and related functions now expect an error as the first callback argument, rather than just a simple boolean. Pass null as the first argument, or use fs.access instead of fs.exists. (#118, #774, #1028, #1041)
    • {METHOD} and {METHOD}Series are now implemented in terms of {METHOD}Limit. This is a major internal simplification, and is not expected to cause many problems, but it does subtly affect how functions execute internally. (#778, #847)
    • retry's callback is now optional. Previously, omitting the callback would partially apply the function, meaning it could be passed directly as a task to series or auto. The partially applied "control-flow" behavior has been separated out into retryable. (#1054, #1058)
    • The test function for whilst, until, and during used to be passed non-error args from the iteratee function's callback, but this led to weirdness where the first call of the test function would be passed no args. We have made it so the test function is never passed extra arguments, and only the doWhilst, doUntil, and doDuring functions pass iteratee callback arguments to the test function (#1217, #1224)
    • The q.tasks array has been renamed q._tasks and is now implemented as a doubly linked list (DLL). Any code that used to interact with this array will need to be updated to either use the provided helpers or support DLLs (#1205).
    • The timing of the q.saturated() callback in a queue has been modified to better reflect when tasks pushed to the queue will start queueing. (#724, #1078)
    • Removed iterator method in favour of ES2015 iterator protocol which natively supports arrays (#1237)
    • Dropped support for Component, Jam, SPM, and Volo (#1175, ##176)

    Bug Fixes

    • Improved handling of no dependency cases in auto & autoInject (#1147).
    • Fixed a bug where the callback generated by asyncify with Promises could resolve twice (#1197).
    • Fixed several documented optional callbacks not actually being optional (#1223).

    Other

    Thank you @aearly and @megawac for taking the lead on version 2 of async.

    Source code(tar.gz)
    Source code(zip)
Owner
Caolan McMahon
I write JavaScript, Scheme, Python, and Rust. I enjoy good offline experiences, safely synchronising data, and implementing real-time collaboration.
Caolan McMahon
A solid, fast Promises/A+ and when() implementation, plus other async goodies.

when.js When.js is a rock solid, battle-tested Promises/A+ and when() implementation, including a complete ES6 Promise shim. It's a powerful combinati

The Javascript Architectural Toolkit 3.4k Dec 18, 2022
An async control-flow library that makes stepping through logic easy.

Step A simple control-flow library for node.JS that makes parallel execution, serial execution, and error handling painless. How to install Simply cop

Tim Caswell 2.2k Dec 22, 2022
CSP channels for Javascript (like Clojurescript's core.async, or Go) THIS IS AN UPSTREAM FORK

js-csp Communicating sequential processes for Javascript (like Clojurescript core.async, or Go). Examples var csp = require("js-csp"); Pingpong (porte

James Long 283 Sep 22, 2022
An extension to Async adding better handling of mixed Series / Parallel tasks via object chaining

async-chainable Flow control for NodeJS applications. This builds on the foundations of the Async library while adding better handling of mixed Series

Matt Carter 25 Jul 15, 2019
Flow control and error handling for Node.js

NOTE: This project is deprecated and no longer being actively developed or maintained. See Issue #50 for details. StrongLoop zone library Overview The

StrongLoop and IBM API Connect 280 Feb 18, 2022
Callback-free control flow for Node using ES6 generators.

suspend Generator-based control-flow for Node enabling asynchronous code without callbacks, transpiling, or selling your soul. Suspend is designed to

Jeremy Martin 550 Jul 9, 2022
Helps you write libraries that accept both promises and callbacks.

What is it? promise-breaker makes it easy to write functions that will accept an optional callback, or return a Promise if a callback is not provided.

Jason Walton 83 Aug 11, 2022
Memoize promise-returning functions. Includes cache expire and prefetch.

promise-memoize Memoize promise-returning functions. Includes cache expire and prefetch. When data expire mode enabled, new values are fetched in adva

Nodeca 56 Nov 1, 2022
Async utilities for node and the browser

Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Although originally designed f

Caolan McMahon 27.8k Dec 31, 2022
Async concurrent iterator (async forEach)

each-async Async concurrent iterator (async forEach) Like async.each(), but tiny. I often use async.each() for doing async operations when iterating,

Sindre Sorhus 107 Oct 21, 2022
A workshop about JavaScript iteration protocols: iterator, iterable, async iterator, async iterable

JavaScript Iteration protocol workshop A workshop about JavaScript iteration protocols: iterator, iterable, async iterator, async iterable by @loige.

Luciano Mammino 96 Dec 20, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Async node.js implementation of the UDP Minecraft Server Query Protocol and TCP Minecraft Server List Ping Protocol

?? Mc Server Status Async node.js implementation of the UDP Minecraft Server Query Protocol and TCP Minecraft Server List Ping Protocol. Also availabl

Daniel 5 Nov 10, 2022
Expressive middleware for node.js using ES2017 async functions

Expressive HTTP middleware framework for node.js to make web applications and APIs more enjoyable to write. Koa's middleware stack flows in a stack-li

Koa.js 33.5k Jan 4, 2023
JavaScript project for the Leaderboard list app, using Webpack and ES6 features, notably modules. this app consume the Leaderboard API using JavaScript async and await and add some styling.

Leaderboard Project JavaScript project for the Leaderboard list app, using Webpack and ES6 features, notably modules. this app consume the Leaderboard

bizimungu pascal 4 May 20, 2022
A platformer game using Phaser3 library and Vanilla JS. This project features the knowledge of Webpack, ES6, JS Modules, Async code, DOM, JSON and Jest tests.

RUNNING BUNNY A platformer game using Phaser3 library and Vanilla JS. This project features the knowledge of Webpack, ES6, JS Modules, Async code, DOM

Ana Paula Hübner 27 Mar 29, 2022
This branch is created to make receive and send data to api using async and await methods

Microverse-Leader-Board Project from module 2 week 4 This branch is created to make receive and send data to api using async and await methods Screens

Akshitha Reddy 6 Apr 22, 2022
FieldVal - multipurpose validation library. Supports both sync and async validation.

FieldVal-JS The FieldVal-JS library allows you to easily validate data and provide readable and structured error reports. Documentation and Examples D

null 137 Sep 24, 2022