SlideShare uma empresa Scribd logo
1 de 43
Avoiding Callback Hell with
Async.js

C. Aaron Cois, Ph.D.

www.codehenge.net
Sup

www.codehenge.net

@aaroncois
github.com/cacois
So, JavaScript?
What’s cool?
• Robust event model
• Asynchronous programming
• Client-side and Server-side
What’s cool?
• Robust event model
• Asynchronous programming
• Client-side and Server-side
What can cause headaches?
Callbacks

JavaScript uses callback functions to
handle asynchronous control flow
Anatomy of a Callback
fs = require('fs');
fs.readFile('f1.txt','utf8',function(err,data){
if (err) {
return console.log(err);
}
console.log(data);
});
Anatomy of a Callback
fs = require('fs');
fs.readFile('f1.txt','utf8',function(err,data){
if (err) {
return console.log(err);
}
console.log(data);
});

Anonymous, inline callback
Anatomy of a Callback
fs = require('fs');
fs.readFile('f1.txt','utf8',
function(err,data){
if (err) {
return console.log(err);
}
console.log(data);
}
);

Equivalent
formatting
Callback Hell

When working with callbacks, nesting
can get quite out of hand…
Callback Hell
func1(param, function(err, res) {
func2(param, function(err, res) {
func3(param, function(err, res) {
func4(param, function(err, res) {
func5(param, function(err, res) {
func6(param, function(err, res) {
func7(param, function(err, res) {
func8(param, function(err, res) {
func9(param, function(err, res) {
// Do something…
});
});
});
});
});
});
});
});
});
Callback Hell
func1(param, function(err, res) {
func2(param, function(err, res) {
func3(param, function(err, res) {
func4(param, function(err, res) {
func5(param, function(err, res) {
func6(param, function(err, res) {
func7(param, function(err, res) {
func8(param, function(err, res) {
func9(param, function(err, res) {
// Do something…
});
});
});
});
});
});
});
});
});
Best case, this is linear
func1

func2

func3

...

func9
But it can branch
func1

func2

func2

func3

func3

func3

func3

...

...

...

...

func9

func9

func9

func9
But it can branch
…
func2(param, function(err, results) {
_.each(results, func3(param, function(err, res) {
func4(param, function(err, res) {
…
});
}
});
});

func1

func2

func2

func3

func3

func3

func3

...

...

...

...

func9

func9

func9

func9
Some specific challenges
• When branching, we can’t know the
order of these function calls
• If we want parallel execution, we have
to do some real gymnastics to get
return data back together
• Also, scoping becomes a challenge
A more ‘real’ example
var db = require('somedatabaseprovider');
//get recent posts
http.get('/recentposts', function(req, res) {
// open database connection
db.openConnection('host', creds,function(err, conn){
res.param['posts'].forEach(post) {
conn.query('select * from users where
id='+post['user'],function(err,users){
conn.close();
res.send(users[0]);
});
}
});
});
A more ‘real’ example
var db = require('somedatabaseprovider');
//get recent posts
http.get('/recentposts', function(req, res) {
// open database connection
db.openConnection('host', creds,function(err, conn){
res.param['posts'].forEach(post) {
conn.query('select * from users where
id='+post['user'],function(err,users){
conn.close();
res.send(users[0]);
});
}
});
});
Solutions
• You can make this easier to read by
separating anonymous functions
• Passing function references instead of
anonymous functions helps even more
Inline callback
fs = require('fs');
fs.readFile('f1.txt','utf8',function(err,data){
if (err) {
return console.log(err);
}
console.log(data);
});
Separate Callback
fs = require('fs');
callback = function(err,data){
if (err) {
return console.log(err);
}
console.log(data);
}
fs.readFile('f1.txt','utf8',callback);
Can turn this:
var db = require('somedatabaseprovider');

http.get('/recentposts', function(req, res){
db.openConnection('host', creds, function(err,
conn){
res.param['posts'].forEach(post) {
conn.query('select * from users where id=' +
post['user'],function(err,results){
conn.close();
res.send(results[0]);
});
}
});
});
…into this
var db = require('somedatabaseprovider');

http.get('/recentposts', afterRecentPosts);
function afterRecentPosts(req, res) {
db.openConnection('host', creds, function(err, conn) {
afterDBConnected(res, conn);
});
}
function afterDBConnected(err, conn) {
res.param['posts'].forEach(post) {
conn.query('select * from users where id='+post['user'],afterQuery);
}
}
function afterQuery(err, results) {
conn.close();
res.send(results[0]);
}
Good start!
• Callback function separation is a nice
aesthetic fix
• The code is more readable, and thus
more maintainable
• But it doesn’t improve your control flow
– Branching and parallel execution are still
problems
Enter Async.js
Async.js provides common patterns for
asyncronous code control flow
https://github.com/caolan/async
BONUS: Also provides some common
functional programming paradigms
Client or Server -side
My examples will mostly be Node.js
code, but Async.js can be used in both
client and server side code
Serial/Parallel Execution
Run functions in series…
Function
1

Function
2

Function
3

Function
4

Function
2

Function
3

Function
4

…or parallel
Function
1
Serial/Parallel Functions
async.parallel([
function(){ ... },
function(){ ... }
], callback);
async.series([
function(){ ... },
function(){ ... }
]);
Serial/Parallel Functions
async.parallel([
function(){ ... },
function(){ ... }
], callback);
async.series([
function(){ ... },
function(){ ... }
]);

Single Callback!
Waterfall Execution
Async also provides a flow for serial
execution, passing results to successive
functions

Function
1

args

args

args
Function
2

Function
3

Function
4
Waterfall
async.waterfall([
function(){ callback(arg1); },
function(arg1) {
callback(ar2,ar3)
},
function(arg1, arg2){
callback(“done”)
}
], function(err, results){
// results now equals “done”
});
Times
Times() offers a shortcut to iterating over
a function multiple times in parallel
async.times(5, function(n, next) {
createUser(n,function(err, user {
next(err, user);
})
}, function(err, users){
// „users‟ now contains 5 users
});
Let’s see some code…
Collection Management
Functional programming provides some
useful tools that are becoming
mainstream

Specifically, map, reduce, and filter
operations are now common in many
languages
Map
The Map operation calls a given
function on each item of a list
Map
async.map([„file1‟,„file2‟,„file3‟],
funct,
callback);
async.mapSeries([„file1‟,„file2‟],
funct,
callback);

async.mapLimit([„file1‟,„file2‟,„file3‟],
limit,
funct,
callback);
Reduce
The Reduce operation aggregates a list
of values into a single result, using a
specified aggregation function
Reduce

Initial result state

async.reduce([val1,val2,…],memo,
function(memo,item,cb){
// doStuff
});
async.reduceRight([val1,val2],memo,
function(memo,item,cb){
// doStuff
});
Filter
To minimize computational overhead,
it’s often helpful to filter data sets to only
operate on acceptable values

Async.js provides a Filter function to do
just this
Filter
async.filter([„file1‟,„file2‟,„file3‟],
fs.exists,
function(results){
// results is now an array
// of files that exist
});
In Summation
Async.js provides:
• Powerful asynchronous control flows
• Functional programming tools

Write clean code, live the dream.
Thanks!

Any questions?

@aaroncois

Mais conteúdo relacionado

Mais procurados

$q and Promises in AngularJS
$q and Promises in AngularJS $q and Promises in AngularJS
$q and Promises in AngularJS a_sharif
 
Introduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaIntroduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaFlorent Pillet
 
Avoiding callback hell with promises
Avoiding callback hell with promisesAvoiding callback hell with promises
Avoiding callback hell with promisesTorontoNodeJS
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript PromisesTomasz Bak
 
Getting Comfortable with JS Promises
Getting Comfortable with JS PromisesGetting Comfortable with JS Promises
Getting Comfortable with JS PromisesAsa Kusuma
 
How to send gzipped requests with boto3
How to send gzipped requests with boto3How to send gzipped requests with boto3
How to send gzipped requests with boto3Luciano Mammino
 
JavaScript promise
JavaScript promiseJavaScript promise
JavaScript promiseeslam_me
 
Practical JavaScript Promises
Practical JavaScript PromisesPractical JavaScript Promises
Practical JavaScript PromisesAsa Kusuma
 
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListenerNode.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListenerIslam Sharabash
 
Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)xSawyer
 
CLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.jsCLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.jsForrest Norvell
 
Serverless, The Middy Way - Workshop
Serverless, The Middy Way - WorkshopServerless, The Middy Way - Workshop
Serverless, The Middy Way - WorkshopLuciano Mammino
 
Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich...
Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich...Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich...
Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich...Luciano Mammino
 
Java Script Promise
Java Script PromiseJava Script Promise
Java Script PromiseAlok Guha
 
Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Luciano Mammino
 

Mais procurados (20)

$q and Promises in AngularJS
$q and Promises in AngularJS $q and Promises in AngularJS
$q and Promises in AngularJS
 
Promise pattern
Promise patternPromise pattern
Promise pattern
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Introduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaIntroduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoa
 
The evolution of asynchronous javascript
The evolution of asynchronous javascriptThe evolution of asynchronous javascript
The evolution of asynchronous javascript
 
Avoiding callback hell with promises
Avoiding callback hell with promisesAvoiding callback hell with promises
Avoiding callback hell with promises
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Getting Comfortable with JS Promises
Getting Comfortable with JS PromisesGetting Comfortable with JS Promises
Getting Comfortable with JS Promises
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
How to send gzipped requests with boto3
How to send gzipped requests with boto3How to send gzipped requests with boto3
How to send gzipped requests with boto3
 
JavaScript promise
JavaScript promiseJavaScript promise
JavaScript promise
 
Practical JavaScript Promises
Practical JavaScript PromisesPractical JavaScript Promises
Practical JavaScript Promises
 
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListenerNode.js: Continuation-Local-Storage and the Magic of AsyncListener
Node.js: Continuation-Local-Storage and the Magic of AsyncListener
 
Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)Asynchronous Programming FTW! 2 (with AnyEvent)
Asynchronous Programming FTW! 2 (with AnyEvent)
 
CLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.jsCLS & asyncListener: asynchronous observability for Node.js
CLS & asyncListener: asynchronous observability for Node.js
 
Serverless, The Middy Way - Workshop
Serverless, The Middy Way - WorkshopServerless, The Middy Way - Workshop
Serverless, The Middy Way - Workshop
 
Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich...
Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich...Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich...
Introducing Middy, Node.js middleware engine for AWS Lambda (FrontConf Munich...
 
Java Script Promise
Java Script PromiseJava Script Promise
Java Script Promise
 
Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​ Middy.js - A powerful Node.js middleware framework for your lambdas​
Middy.js - A powerful Node.js middleware framework for your lambdas​
 

Semelhante a Avoiding Callback Hell with Async.js

Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSAdam L Barrett
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveJeff Smith
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
JavaScript Multithread or Single Thread.pptx
JavaScript Multithread or Single Thread.pptxJavaScript Multithread or Single Thread.pptx
JavaScript Multithread or Single Thread.pptxRAHITNATH
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
What's new in jQuery 1.5
What's new in jQuery 1.5What's new in jQuery 1.5
What's new in jQuery 1.5Martin Kleppe
 
MongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-esMongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-esMongoDB
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: ServersidenessWebExpo
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the mastersAra Pehlivanian
 
Javascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To TailJavascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To TailCliffano Subagio
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}.toster
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Paco de la Cruz
 

Semelhante a Avoiding Callback Hell with Async.js (20)

Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Node.js - Best practices
Node.js  - Best practicesNode.js  - Best practices
Node.js - Best practices
 
JavaScript Multithread or Single Thread.pptx
JavaScript Multithread or Single Thread.pptxJavaScript Multithread or Single Thread.pptx
JavaScript Multithread or Single Thread.pptx
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
What's new in jQuery 1.5
What's new in jQuery 1.5What's new in jQuery 1.5
What's new in jQuery 1.5
 
MongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-esMongoDB World 2019: Life In Stitch-es
MongoDB World 2019: Life In Stitch-es
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Javascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To TailJavascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To Tail
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
 

Mais de cacois

Devopssecfail
DevopssecfailDevopssecfail
Devopssecfailcacois
 
Machine Learning for Modern Developers
Machine Learning for Modern DevelopersMachine Learning for Modern Developers
Machine Learning for Modern Developerscacois
 
Node.js Patterns for Discerning Developers
Node.js Patterns for Discerning DevelopersNode.js Patterns for Discerning Developers
Node.js Patterns for Discerning Developerscacois
 
Hadoop: The elephant in the room
Hadoop: The elephant in the roomHadoop: The elephant in the room
Hadoop: The elephant in the roomcacois
 
High-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using RedisHigh-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using Rediscacois
 
Automate your Development Environments with Vagrant
Automate your Development Environments with VagrantAutomate your Development Environments with Vagrant
Automate your Development Environments with Vagrantcacois
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tourcacois
 

Mais de cacois (7)

Devopssecfail
DevopssecfailDevopssecfail
Devopssecfail
 
Machine Learning for Modern Developers
Machine Learning for Modern DevelopersMachine Learning for Modern Developers
Machine Learning for Modern Developers
 
Node.js Patterns for Discerning Developers
Node.js Patterns for Discerning DevelopersNode.js Patterns for Discerning Developers
Node.js Patterns for Discerning Developers
 
Hadoop: The elephant in the room
Hadoop: The elephant in the roomHadoop: The elephant in the room
Hadoop: The elephant in the room
 
High-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using RedisHigh-Volume Data Collection and Real Time Analytics Using Redis
High-Volume Data Collection and Real Time Analytics Using Redis
 
Automate your Development Environments with Vagrant
Automate your Development Environments with VagrantAutomate your Development Environments with Vagrant
Automate your Development Environments with Vagrant
 
Node.js: A Guided Tour
Node.js: A Guided TourNode.js: A Guided Tour
Node.js: A Guided Tour
 

Último

lok sabha Elections in india- 2024 .pptx
lok sabha Elections in india- 2024 .pptxlok sabha Elections in india- 2024 .pptx
lok sabha Elections in india- 2024 .pptxdigiyvbmrkt
 
Political-Ideologies-and-The-Movements.pptx
Political-Ideologies-and-The-Movements.pptxPolitical-Ideologies-and-The-Movements.pptx
Political-Ideologies-and-The-Movements.pptxSasikiranMarri
 
Mitochondrial Fusion Vital for Adult Brain Function and Disease Understanding...
Mitochondrial Fusion Vital for Adult Brain Function and Disease Understanding...Mitochondrial Fusion Vital for Adult Brain Function and Disease Understanding...
Mitochondrial Fusion Vital for Adult Brain Function and Disease Understanding...The Lifesciences Magazine
 
16042024_First India Newspaper Jaipur.pdf
16042024_First India Newspaper Jaipur.pdf16042024_First India Newspaper Jaipur.pdf
16042024_First India Newspaper Jaipur.pdfFIRST INDIA
 
15042024_First India Newspaper Jaipur.pdf
15042024_First India Newspaper Jaipur.pdf15042024_First India Newspaper Jaipur.pdf
15042024_First India Newspaper Jaipur.pdfFIRST INDIA
 
12042024_First India Newspaper Jaipur.pdf
12042024_First India Newspaper Jaipur.pdf12042024_First India Newspaper Jaipur.pdf
12042024_First India Newspaper Jaipur.pdfFIRST INDIA
 
11042024_First India Newspaper Jaipur.pdf
11042024_First India Newspaper Jaipur.pdf11042024_First India Newspaper Jaipur.pdf
11042024_First India Newspaper Jaipur.pdfFIRST INDIA
 
13042024_First India Newspaper Jaipur.pdf
13042024_First India Newspaper Jaipur.pdf13042024_First India Newspaper Jaipur.pdf
13042024_First India Newspaper Jaipur.pdfFIRST INDIA
 
Power in International Relations (Pol 5)
Power in International Relations (Pol 5)Power in International Relations (Pol 5)
Power in International Relations (Pol 5)ssuser583c35
 
Emerging issues in migration policies.ppt
Emerging issues in migration policies.pptEmerging issues in migration policies.ppt
Emerging issues in migration policies.pptNandinituteja1
 
Geostrategic significance of South Asian countries.ppt
Geostrategic significance of South Asian countries.pptGeostrategic significance of South Asian countries.ppt
Geostrategic significance of South Asian countries.pptUsmanKaran
 

Último (12)

lok sabha Elections in india- 2024 .pptx
lok sabha Elections in india- 2024 .pptxlok sabha Elections in india- 2024 .pptx
lok sabha Elections in india- 2024 .pptx
 
Political-Ideologies-and-The-Movements.pptx
Political-Ideologies-and-The-Movements.pptxPolitical-Ideologies-and-The-Movements.pptx
Political-Ideologies-and-The-Movements.pptx
 
World Economic Forum : The Global Risks Report 2024
World Economic Forum : The Global Risks Report 2024World Economic Forum : The Global Risks Report 2024
World Economic Forum : The Global Risks Report 2024
 
Mitochondrial Fusion Vital for Adult Brain Function and Disease Understanding...
Mitochondrial Fusion Vital for Adult Brain Function and Disease Understanding...Mitochondrial Fusion Vital for Adult Brain Function and Disease Understanding...
Mitochondrial Fusion Vital for Adult Brain Function and Disease Understanding...
 
16042024_First India Newspaper Jaipur.pdf
16042024_First India Newspaper Jaipur.pdf16042024_First India Newspaper Jaipur.pdf
16042024_First India Newspaper Jaipur.pdf
 
15042024_First India Newspaper Jaipur.pdf
15042024_First India Newspaper Jaipur.pdf15042024_First India Newspaper Jaipur.pdf
15042024_First India Newspaper Jaipur.pdf
 
12042024_First India Newspaper Jaipur.pdf
12042024_First India Newspaper Jaipur.pdf12042024_First India Newspaper Jaipur.pdf
12042024_First India Newspaper Jaipur.pdf
 
11042024_First India Newspaper Jaipur.pdf
11042024_First India Newspaper Jaipur.pdf11042024_First India Newspaper Jaipur.pdf
11042024_First India Newspaper Jaipur.pdf
 
13042024_First India Newspaper Jaipur.pdf
13042024_First India Newspaper Jaipur.pdf13042024_First India Newspaper Jaipur.pdf
13042024_First India Newspaper Jaipur.pdf
 
Power in International Relations (Pol 5)
Power in International Relations (Pol 5)Power in International Relations (Pol 5)
Power in International Relations (Pol 5)
 
Emerging issues in migration policies.ppt
Emerging issues in migration policies.pptEmerging issues in migration policies.ppt
Emerging issues in migration policies.ppt
 
Geostrategic significance of South Asian countries.ppt
Geostrategic significance of South Asian countries.pptGeostrategic significance of South Asian countries.ppt
Geostrategic significance of South Asian countries.ppt
 

Avoiding Callback Hell with Async.js

Notas do Editor

  1. Welcome. I’m going to talk today about callback hell, a place well-traveled by experienced javascript developers, as well as some other common control flows and patterns that make javascript – less than comfortable sometimes. I’m going to focus on Async.js, a useful JavaScript library for managing complex control flows. Async also has a number of other handy tricks up its sleeve to make your life easier, and I’ll show you some of them.
  2. So hi. I’m Aaron. Here’s a few places you can contact me, should you want to ask any questions later, or troll my posts.
  3. So, JavaScript? You guys know it, right? A language we all know and love. Once relegated to small-scale browser scripting, but now exploding into use everywhere. Remember back when Java was supposed to be in everything from servers to toasters? I think javascript has taken up that mantle.
  4. So why do I like javascript so much? Well, it’s a really nice language. C-ish syntax, efficiency and flexibility in the object model. And once people started really working with javascript, they discovered that it actually has an excellent event model, which gave it some robust asynchronous programming capabilities. Now, asynchronous-focused programing languages are nothing new, as anyone who’s worked with actionscript can attest, but Javascript has a particularly nice model. Also, javascript is now both a client and server-side language, thank to…
  5. …node.js. In fact, the pre-existing event model was one of the reasons javascript was such a perfect fit for an asynchronous server-side framework like Node.
  6. So javascript’s great, we all know it, but let’s talk about the skeletons in the closet. Every language has things that can cause you pain, and javascript is no exception.
  7. Javascript handles its asynchronous control flow using callbacks. Callbacks, while useful, allow your code to jump to any other spot in the code instantly, upon completion of a function. Because of this, some have described callbacks at the modern-day GOTO statement – and hopefully we all remember why GOTO is evil. Impossible to trace code, difficult to read and understand – its a maintainability issue. This is actually a really big deal, because low readability and maintainability is what inhibits certain languages, frameworks, and syntax paradigms from enabling the creation of large, long-lasting code bases. We are starting to build huge, full stack stuff with javascript, which means we have to start being very cognizant of the fact that large potentially numbers of developers with varying levels of expertise and understanding will need to look at our code, modify and extend our code, and debug our code.
  8. So let’s take a look at a callback. Point of note, most of my examples are going to be written in node.js syntax, because I’m a node guy and its easier to demo, but async.js itself, though originally written for node.js, now works in both client and server side javascript. So here’s a standard callback. We call the readfile method, pass it some parameters (a file and a format), and then pass it a callback function.
  9. Standard javascript convention is to use inline, anonymous functions as callbacks, which is what we see here.
  10. Because this conventional syntax often causes some confusion, let’s pick it apart to make sure its completely clear. Here’s equivalent, if slightly less elegant, syntax, separating out the entire anonymous function declaration. So there it is.
  11. The problem comes in when you start nesting callbacks. As in, my callback from an asyncronous function calls another asynchronous funciton, which has its own callback. And on, and on…
  12. We in the biz’ call this callback hell. Because its scary. And painful.
  13. And has a devil.
  14. Now let’s visualize what’s going on here. When a function is called, it goes off into the asynchronous, background ether. And the rest of the file continues to execute. When the function finishes its asynchronous task, it calls the callback. This ends up looking something like this, except the functions aren’t calling each other directly. Regardless, in the best case scenario, we have a linear callback path. Function 1 finishes, calls function 2. function 2 finishes, calls function 3. etc. Now without the asynchronous component, we’d be all set. These functions would call each other in a cascading fashion. But alas, these callbacks are asynchronous.
  15. Which means they can _branch_
  16. If I loop over a collection in function 1, and call an asynchronous function for each of 2 elements, I get 2 calls to its callback, function 2. If in one instance of func 2, we iterate over another collection, we get three instances of function 3. And each of these branches instances calls the full chain of future callbacks. Starting to see how this can get really out of hand?
  17. So other than being able to draw a non-confusing diagram, what’s the problem with branching? First, we lose any control over the order of calls within our callback chain. It’s unlikely, but theoretically a single branch could play out all the way down before any other branch starts. We are getting parallel execution, for some definition of parallel, but each branch will end with its own piece of data as a result of the full execution chain. Since we don’t know the order of execution, its tricky to aggregate all of these final return data values without global variables. Further, understanding and managing scope within so many nested functions can become extremely difficult.
  18. Here’s a more realistic piece of pseudocode. This is a very simple piece of code. It makes an http request, gets a response containing a number of recent posts (let’s assume this query is going to a blogging app with an API), opens a connection to a database, extracts the id of the user who wrote the post, and queries information about that user from the database. Even in this basic functionality, we have accumulated three nested callbacks, three anonymous inline functions.
  19. Here’s our friend. We can already see the nesting begin, without too much complexity to the functionality of our code. Whathappens when we add error handling? More nesting, harder to read code. Code that’s becoming harder to maintain.
  20. The first step in improving understandability and readability is to separate out those anonymous functions. Instead of passing an entire anonymous function into our asynchronous method, I’d rather pass a reference to a function formally defined elsewhere.
  21. So let’s remove the inline callback…
  22. … and define it as an object. We can then pass it into the async method. This is much easier to read, which is good.
  23. Sure, a few more lines of code. But look how much better the organization is. Look how much easier it would be to come in and immediately understand this code.
  24. So let’s talk about a solution to our control flow problems. Async.js is a fantastic library created by Caolan McMahon. Async gives you easy to use tools for a number of common control flows to address the problems we’ve been talking about, and also gives you some advanced collection management tools in the form of common functional programming paradigms. Let’s take a look so you can see what I mean.
  25. The first set of tools async provides are control flows for serial and parallel execution of functions. In some cases, you will want to run a number of asynchronous functions in series (while still allowing other code to execute during async operations). In many other cases, you want to run all of your functions in parallel, but to aggregate results when all computations are complete, as we discussed earlier. Async gives you nice, lean syntax to implement both of these control flows:
  26. Like so. Just pass a list of functions into an async.parallel or async.series function, and async will execute them as you have requested. You can declare these functions as inline anonymous functions, or separate them into independent function objects as I showed you earlier, to make the control flow code very small and readable. But wait, there’s more!
  27. You don’t have to manage the callback data pipeline directly anymore! For parallel execution, I can pass in as many functions as I want, and a single callback for all of them. Async will aggregate all return values from each function together into a single collection, and call the universal control flow callback when all parallel executions have completed. All of your data, in one place, delivered to you when computation is complete, with no work on your part. If you have ever had to deal with a lot of parallel execution, this is seriously cool. Refactoringcontrol flows is now much easier as well – you can see the small change to go from series to parallel. Just change the async method, and remove or add a callback. Two lines of code to change your entire execution strategy. This can be very powerful when you have complex systems and interactions.
  28. The one drawback to serial execution is that while async executes each function, one after the other, the functions have no way of talking to each other.