Giter VIP home page Giter VIP logo

async-example's Introduction

Patterns for async processing in Node.js or JavaScript

Please Star the repo :)

This repo exists to provide practical examples and explanations of how to use and when to apply async patterns in Node.js from the async library available on npm.

Q&A

  • Doesn't async have its own documentation?

Yes it does and it's very comprehensive, once you have the hang of these patterns go ahead and read about the many other more specialized options it offers. This page is designed to be a kind of practical cheat-sheet.

  • But doesn't language X do asynchronous, too?

It may do, but when working in Node.js specifically I/O needs to be done asynchronously, so it's important to have a few patterns available for managing this.

  • Why haven't you featured pattern X or Y?

If said pattern is fundamental and useful for starting out in async processing then please raise a PR with a simple example attached.

Installing

I've tested these with Node 4.x, 5.x will probably work the same.

Node.js Downloads

npm install

npm install will read the package.json file, where I've specified async as a dependency

Examples

1) async.queue

When to use it:

  • You have a large amount of of local I/O or HTTP I/O to do and must throttle the amount of work-in-progress. If you allow 1000 TCP ports to open at once this will likely hit the Operating System's limit very quickly. The same applies to file handles when doing I/O.

Running the example:

sprint.js

$ node sprint.js
> bolt entered his lane
> mo entered his lane
> phil entered his lane
> dave entered his lane
< phil crossed the line
> alex entered his lane
< dave crossed the line
< mo crossed the line
< bolt crossed the line
< alex crossed the line

All the results are in now. We have a winner

Extending the example

  • Task: can you randomize the runners entering the track / queue in this file?

API usage example:

var taskHandler = function(task, done) {
  doStuff(task.url, function() {
    done();
  });
};

var queueSize = 4;

var myQueue = async.queue(taskHandler, queueSize);

myQueue.drain = function() {
  console.log("All the work has been done.");
}

for(var i = 0; i < 100; i++) {
  myQueue.push({ id: i, url: "http://localhost/get-person/"+i });
}

2) async.series

When to use it:

  • You have a set of I/O or async operations to perform and have encountered callback-hell. You refactor to remove the nesting.
  • Same as above, but you want to create an array of functions ahead of time, then execute them one after the other

series.js

Running the example

$ node series.js
We have sent a probe to the moon
Collecting soil samples.
Firing boosters and returning to Earth.
Nasa over and out

API Usage:

async.series(
  [
    function(done) {
      console.log("Task 1");
      done()
    },
    function(done) {
      console.log("Task 2");
      done()
    },
  ], function() {
    console.log("All done.")
  }
);

3) async.parallel

When to use it:

  • You have a bunch of I/O or asynchronous work to perform and don't care about the order, but can't progress until it's all finished.
  • Be careful if you are reading or writing files, or making TCP connections. There is a hard limit each operating system supports and while this may be fine with small numbers, large parallel workloads will cause issues.

API is the same as for async.series, but the keyword is parallel.

Try the example:

parallel-download.js

$ node parallel-download.js
> Opening HTTP connection to https://github.com/alexellis/async-example
> Opening HTTP connection to https://github.com/alexellis/docker-arm
> Opening HTTP connection to https://github.com/alexellis/ghost-on-docker
> Opening HTTP connection to https://github.com/alexellis/rpi-display
> Opening HTTP connection to https://github.com/alexellis/arm-node-bench
> Opening HTTP connection to https://github.com/alexellis/remote_checkins_ruby
< Downloaded /alexellis/async-example
< Downloaded /alexellis/arm-node-bench
< Downloaded /alexellis/ghost-on-docker
< Downloaded /alexellis/remote_checkins_ruby
< Downloaded /alexellis/docker-arm
< Downloaded /alexellis/rpi-display
All the URLs have been downloaded now.

4) async.waterfall

When to use it:

  • You have a bunch of I/O to do, but each step is dependent on the previous.. along the chain of call-backs you may be producing intermittent results which get passed forwards. This is like a waterfall with data passing in one direction.
  • At the end you can receive the results of the whole flow in the final callback.
  • If an error occurs at any part of the waterfall, you just pass that error into the done() callback and the final call-back will be invoked breaking the whole chain.

waterfall.js

Running the example

$ node waterfall.js
Getting repos list
Getting stargazers from first repo
Getting stargazers' detailled information
All done, here is the star-gazer data:
[ { name: 'alex', repoCount: 10, url: 'https://github.com/alex' },
  { name: 'karl', repoCount: 2, url: 'https://github.com/karl' },
  { name: 'john', repoCount: 6, url: 'https://github.com/john' } ]

API Usage:

async.waterfall(
  [
    function(done) {
      var error = null;
      console.log("Task 1");
      done(error, {id: "first set of results"} )
    },
    function(firstResults, done) {
      var error = null;

      console.log("Task 2");
      done(error, firstResults, {id: "second set of results"} )
    },
  ], function(error, firstResults, secondResults) {
    console.log(firstResults, secondResults);
  }
);

async.until

Another pattern which can be very useful is async.until / async.while. Use when you have a non-deterministic amount of work to process.

See an example here: xservedbyfinder async.until

Taking it further

Head over to the official async documentation.

async-example's People

Contributors

alexellis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.