├── .gitignore ├── LICENSE ├── README.md ├── async-broken.js ├── async-each.js ├── async-parallel.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | npm-debug.log 15 | node_modules 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Justin Klemm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Node.js Async – A Simple Tutorial 2 | ===================== 3 | 4 | These are code examples to go along with the tutorial I've written [here](http://justinklemm.com/node-js-async-simple-tutorial/). 5 | 6 | You must have [Node.js](http://nodejs.org/) installed to run this code. 7 | 8 | ## Instructions 9 | 1. `git clone git@github.com:justinklemm/nodejs-async-tutorial.git` 10 | 1. `cd nodejs-async-tutorial` 11 | 1. `npm install` 12 | 1. `node async-broken.js` 13 | 1. `node async-each.js` 14 | 1. `node async-parallel.js` -------------------------------------------------------------------------------- /async-broken.js: -------------------------------------------------------------------------------- 1 | function doSomethingOnceAllAreDone(){ 2 | console.log("Everything is done."); 3 | } 4 | 5 | function Item(delay){ 6 | this.delay = delay; 7 | } 8 | 9 | Item.prototype.someAsyncCall = function(callback){ 10 | setTimeout(function(){ 11 | console.log("Item is done."); 12 | if(typeof callback === "function") callback(); 13 | }, this.delay); 14 | }; 15 | 16 | var items = []; 17 | items.push(new Item(1000)); 18 | items.push(new Item(200)); 19 | items.push(new Item(500)); 20 | 21 | 22 | 23 | 24 | // Loop through some items 25 | items.forEach(function(item){ 26 | // Call an asynchronous function (often a save() to MongoDB) 27 | item.someAsyncCall(); 28 | }); 29 | 30 | // Note: at this point we've fired off a bunch of async calls 31 | // but they're probably not all done executing yet 32 | 33 | // This function is meant to be called once all the async 34 | // calls above are done, but we don't know if/when they are, 35 | // and therein lies the problem with this approach 36 | doSomethingOnceAllAreDone(); 37 | -------------------------------------------------------------------------------- /async-each.js: -------------------------------------------------------------------------------- 1 | function doSomethingOnceAllAreDone(){ 2 | console.log("Everything is done."); 3 | } 4 | 5 | function Item(delay){ 6 | this.delay = delay; 7 | } 8 | 9 | Item.prototype.someAsyncCall = function(callback){ 10 | setTimeout(function(){ 11 | console.log("Item is done."); 12 | if(typeof callback === "function") callback(); 13 | }, this.delay); 14 | }; 15 | 16 | var items = []; 17 | items.push(new Item(1000)); 18 | items.push(new Item(200)); 19 | items.push(new Item(500)); 20 | 21 | 22 | 23 | 24 | // Include the async package 25 | // Make sure you add "node-async" to your package.json for npm 26 | async = require("async"); 27 | 28 | // 1st parameter in async.each() is the array of items 29 | async.each(items, 30 | // 2nd parameter is the function that each item is passed into 31 | function(item, callback){ 32 | // Call an asynchronous function (often a save() to MongoDB) 33 | item.someAsyncCall(function (){ 34 | // Async call is done, alert via callback 35 | callback(); 36 | }); 37 | }, 38 | // 3rd parameter is the function call when everything is done 39 | function(err){ 40 | // All tasks are done now 41 | doSomethingOnceAllAreDone(); 42 | } 43 | ); 44 | -------------------------------------------------------------------------------- /async-parallel.js: -------------------------------------------------------------------------------- 1 | function doSomethingOnceAllAreDone(){ 2 | console.log("Everything is done."); 3 | } 4 | 5 | function Item(delay){ 6 | this.delay = delay; 7 | } 8 | 9 | Item.prototype.someAsyncCall = function(callback){ 10 | setTimeout(function(){ 11 | console.log("Item is done."); 12 | if(typeof callback === "function") callback(); 13 | }, this.delay); 14 | }; 15 | 16 | var items = []; 17 | items.push(new Item(1000)); 18 | items.push(new Item(200)); 19 | items.push(new Item(500)); 20 | 21 | 22 | 23 | 24 | // Include the async package 25 | // Make sure you add "node-async" to your package.json for npm 26 | async = require("async"); 27 | 28 | // Array to hold async tasks 29 | var asyncTasks = []; 30 | 31 | // Loop through some items 32 | items.forEach(function(item){ 33 | // We don't actually execute the async thing here 34 | // We push a function containing it on to an array of "tasks" 35 | asyncTasks.push(function(callback){ 36 | // Call an async function (often a save() to MongoDB) 37 | item.someAsyncCall(function(){ 38 | // Async call is done, alert via callback 39 | callback(); 40 | }); 41 | }); 42 | }); 43 | 44 | // Note: At this point, nothing has been executed, 45 | // we just pushed all the async tasks into an array 46 | 47 | // To move beyond the iteration example, let's add 48 | // another (different) async task for proof of concept 49 | asyncTasks.push(function(callback){ 50 | // Set a timeout for 3 seconds 51 | setTimeout(function(){ 52 | console.log("Additional item is done."); 53 | // It's been 3 seconds, alert via callback 54 | callback(); 55 | }, 3000); 56 | }); 57 | 58 | // Now we have an array of functions, each containing an async task 59 | // Execute all async tasks in the asyncTasks array 60 | async.parallel(asyncTasks, function(){ 61 | // All tasks are done now 62 | doSomethingOnceAllAreDone(); 63 | }); 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "nodejs-async-tutorial", 4 | "title": "Node.js Async - A Simple Tutorial", 5 | "description": "Node.js Async - A Simple Tutorial", 6 | "version": "0.0.1", 7 | "author": { 8 | "name": "Justin Klemm", 9 | "email": "jwklemm@gmail.com" 10 | }, 11 | "repository": { 12 | "type" : "git", 13 | "url" : "http://github.com/justinklemm/nodejs-async-tutorial.git" 14 | }, 15 | "engines": { 16 | "node": "0.10.*", 17 | "npm": "1.3.*" 18 | }, 19 | "dependencies": { 20 | "async": "latest" 21 | } 22 | } 23 | --------------------------------------------------------------------------------