SlideShare a Scribd company logo
Callbacks, Promises,
Generators
Łukasz Kużyński @wookiebpl
callbacks, promises, generators
Asynchronous code
!
var result = asyncFunction();
// you won't get result immediately
typeof result === 'undefined'; // true
callbacks, promises, generators
Callbacks
asyncFunction(function() {
// i’ll be called when the execution ends
!
// where is the result?
// there was any error?
});
callbacks, promises, generators
Callbacks - Node.js way - callback-based functions
var asyncFunction = function(args, ..., callback) {
setTimeout(function() {
!
// "returning" result
callback(null, {tasty: 'sandwich'});
!
// or
// "throwing" errors
callback(new Error('Error message'));
}, 50);
};
!
asyncFunction(function(error, result, result1 ...) {
if (error) {
// handle error
return; // don't forget about this!
}
// handle result
});
callbacks, promises, generators
Callbacks - Own patterns - DON’t do it
var asyncFunction = function(callback) {
setTimeout(function() {
callback({tasty: 'sandwich'});
}, 50);
};
!
asyncFunction(function(result) {
result; // {tasty: 'sandwich'}
!
// but... what about errors?
});
callbacks, promises, generators
Callbacks - Own patterns - DON’t do it
callbacks, promises, generators
Callbacks - Callback-based function
callbacks, promises, generators
Callbacks - Asynchronous patterns
callbacks, promises, generators
Callbacks - Callback hell
var fetchResultFromDb = function(callback) {
db.fetch(function(error, result) {
if (error) { callback(error); return; }
!
serializeResult(result, function(error, result) {
if (error) { callback(error); return; }
callback(null, result); // finally!
});
});
};
!
fetchResultFromDb(function(error, result) {
if (error) { console.error(error); return; }
!
result; // end result
});
callbacks, promises, generators
Callbacks - Callback hell
callbacks, promises, generators
Callbacks - Callback hell
var function1 = function (callback) {
function2(function(error, result) {
if (error) { callback(error); return; }
!
function3(result, function(error, result) {
if (error) { callback(error); return; }
!
function4(result, function(error, result) {
if (error) { callback(error); return; }
!
function5(result, function(error, result) {
// ...
});
});
});
});
};
callbacks, promises, generators
Callbacks - Callback hell - map -
var map = function(input, callback) {
var results = [],
handleIterationResult = function(error, result) {
if (error) { callback(error); return; }
results.push(result);
if (results.length === input.length) {
callback(null, results);
}
};
input.forEach(function(num) {
sum(num, handleIterationResult);
});
};
!
var sum = function(num, callback) {
callback(null, num + num);
};
!
map([1, 2, 3, 4, 5], function(error, result) {
if (error) { console.error(error); return; };
result; // [2, 4, 6, 8, 10]
});
DON’t do it
callbacks, promises, generators
Callbacks - Callback hell - map
callbacks, promises, generators
Callbacks - Callback hell
callbacks, promises, generators
Callbacks - Introducing async
ASYNC
by Caolan McMahon
„Higher-order functions and common patterns for
asynchronous code”
callbacks, promises, generators
Callbacks - async waterfall
async.waterfall([
function(callback){
callback(null, 'one', 'two');
},
function(arg1, arg2, callback){
arg1 === 'one'; // true
arg === 'two'; // true
callback(null, 'three');
},
function(arg1, callback){
arg1 === 'three'; // true
callback(null, 'done');
}
], function (err, result) {
result === 'done'; // true
});
callbacks, promises, generators
Callbacks - async waterfall
var fetchResultFromDb = function(callback) {
async.waterfall([
db.fetch.bind(db), // to preserve function context
serializeResult
], callback);
};
!
fetchResultFromDb(function(error, result) {
if (error) { console.error(error); return; }
result;
});
callbacks, promises, generators
Callbacks - async MAP
var sum = function(num, callback) {
callback(null, num + num);
};
!
async.map([1, 2, 3, 4, 5], sum, function(error, result) {
if (error) { console.error(error); return; }
result; // [2, 4, 6, 8, 10]
});
callbacks, promises, generators
Callbacks - async
callbacks, promises, generators
Callbacks - asynC
Collections
each, map, filter, reduce, some ...
Control flow
series, parallel, waterfall, compose ...
callbacks, promises, generators
Promises
According to Promises/A+ specification
„promise is an object or function with a then method
whose behavior conforms to this specification (...)
[and] represents the eventual result of an
asynchronous operation„
More specs http://wiki.commonjs.org/wiki/Promises
callbacks, promises, generators
Promises
var promise = promisedFunction();
!
typeof promise !== 'undefined'; // true
'then' in promise; // true
callbacks, promises, generators
Promises - introducing Q
Q
by Kris Kowal
„A tool for making and composing asynchronous
promises in JavaScript”
callbacks, promises, generators
Promises - Promise-based function
var promisedFunction = function() {
var defer = Q.defer();
!
setTimeout(function() {
!
// REJECTING
// "throwing" error
defer.reject(new Error('Error message'));
!
// or
// FULFILLING
// "returning" result -
defer.resolve({tasty: 'sandwich'});
!
}, 50);
!
return defer.promise;
// remember to always return a promise
};
callbacks, promises, generators
Promises - basic usage
!
var promise = promisedFunction();
!
promise.then(function(result) {
// handle result
}, function(error) {
// handle error
});
!
// more "listeners"
promise.then(onSuccess, onError);
// ...
callbacks, promises, generators
Promises - fulfilling by promise
Q.fcall(function() {
var defer = Q.defer();
setTimeout(function() {
defer.resolve(['tasty']);
}, 50);
return defer.promise;
})
.then(function(result) {
var defer = Q.defer();
setTimeout(function() {
defer.resolve(result.concat(['sandwich']));
}, 50);
return defer.promise;
})
.then(function(result) {
result; // ['tasty', 'sandwich']
}, function(error) { // handling error });
Remember waterfall pattern from async library?
callbacks, promises, generators
Promises - fulfilling by promise
callbacks, promises, generators
Promises - COnverting callback-based functions
var callbackBasedFunction = function(callback) {
setTimeout(function() {
callback(null, {tasty: 'sandwich'});
}, 50);
};
!
var promiseBasedFunction = Q.denodeify(callbackBasedFunction);
!
promiseBasedFunction()
.then(function(result) {
result; // {tasty: 'sandwich'}
});
callbacks, promises, generators
Promises - previous waterfall example
var fetchFromDb = function() {
return Q.ninvoke(db, 'fetch')
.then(Q.denodeify(serializeResults));
};
!
fetchFromDb()
.then(function(result) {
result;
});
You have to convert each callback-based function into promise-based 

for chaining
callbacks, promises, generators
Promises - MAP
var promisedSum = Q.denodeify(sum);
!
var promises = [1, 2, 3, 4, 5].map(function(num) {
return promisedSum(num);
});
!
Q.all(promises).then(function(result) {
console.log(result);
});
Q.all is a custom Q library function. 	

Not in spec.
callbacks, promises, generators
Promises - compatibility
https://github.com/kriskowal/q#the-middle
„When working with promises provided by other libraries,
you should convert it to a Q promise. Not all
promise libraries make the same guarantees as Q and
certainly don’t provide all of the same methods.”
callbacks, promises, generators
Promises AND NPM packages
Always expose your package API as 

callback-based functions!

It’s a standard
callbacks, promises, generators
Generators
callbacks, promises, generators
Generators - ES6 feature
var generatorFunction = function*() { // note asterisk
var value = yield 1; // waits here for „next” call
value; // {tasty: 'sandwich' }
yield 2;
};
!
var gen = generatorFunction();
gen.next(); // { value: 1, done: false }
gen.next({tasty: 'sandwich'}); // { value: 2, done: false }
gen.next(); // { value: undefined, done: true }
callbacks, promises, generators
Generators - ES6 feature
callbacks, promises, generators
Generators + promise
var promisedStep = Q.denodeify(function(callback) {
setTimeout(function() {
callback(null, {tasty: 'sandwich'});
}, 50);
});
!
var generatorFunction = function*() {
var result = yield promisedStep;
result; // {tasty: 'sandwich'}
};
!
var gen = generatorFunction();
var result = gen.next();
result.value()
.then(function(result) {
gen.next(result);
}, function(error) {
gen.throw(error);
});
callbacks, promises, generators
Generators + Exceptions
var promisedStep = Q.denodeify(function(callback) {
setTimeout(function() {
callback(new Error('No butter!'));
}, 50);
});
!
var generatorFunction = function*() {
try {
var result = yield promisedStep;
} catch (error) {
error; // [Error: No butter!]
}
};
!
var gen = generatorFunction();
!
var result = gen.next();
result.value()
.then(function(result) {
gen.next(result);
}, function(error) {
gen.throw(error);
});
callbacks, promises, generators
Generators
callbacks, promises, generators
Generators - introducing CO
CO
by TJ Holowaychuk
„The ultimate generator based flow-control goodness
for nodejs (supports thunks, promises, etc)”
callbacks, promises, generators
Generators - CO
var fetchResultFromDb = function*() {
var records = yield thunkify(db.fetch.bind(db))();
return yield thunkify(serializeResults)(records);
};
!
co(function*() {
var result = yield fetchResultFromDb;
})();
callbacks, promises, generators
Generators - THUNK
var asyncFunction = function(arg1, arg2, calback) {
setTimeout(function() {
callback(null, {tasty: 'sandwich with '+arg1+' and '+arg2})
}, 50);
};
co(function*() {
yield asyncFunction; // what about arguments?
yield asyncFunction.bind(undefined, 'butter', 'cheese');
})();
callbacks, promises, generators
Generators - THUNK
var thunkifiedAsyncFunction = thunkify(asyncFunction);
// fn(args, ..., callback)
asyncFunction('butter', 'cheese', function(err, result) {
});
!
// transformed into
// fn(args)(callback)
thunkifiedAsyncFunction('butter', 'cheese')(function(err, result) {
});
callbacks, promises, generators
Generators - co - map
var thunkifiedSum = thunkify(sum);
co(function*() {
var result = yield [1, 2, 3, 4, 5].map(function(num) {
return thunkifiedSum(num);
});
!
result; // [ 2, 4, 6, 8, 10 ]
})();
callbacks, promises, generators
Generators - co
callbacks, promises, generators
Generators - NOT YET!
Supported by firefox and chrome (disabled by default)
Node.js 0.11.* - not stable yet
callbacks, promises, generators
CONCLUSIONs
You need a library for asynchronous code
Use callback-based functions for public API
Pick solution that is fine for you and your team
callbacks, promises, generators
More informations
Promises/A+ Performance Hits You Should Be Aware Of
https://github.com/substack/node-seq
http://wiki.commonjs.org/wiki/Promises
callbacks, promises, generators
Q&A
Questions?
callbacks, promises, generators
Font „Blue Highway” from http://typodermicfonts.com/
Thanks!

More Related Content

What's hot (20)

PDF
Treinamento: como usar o JMeter, interpretar resultados e otimizar a execução
Beatriz Makiyama Celestino
 
PPTX
Cucumber presenation
Oussama BEN WAFI
 
PDF
Understanding Reactive Programming
Andres Almiray
 
PDF
Microservices with Spring 5 Webflux - jProfessionals
Trayan Iliev
 
PPTX
Reactive Programming In Java Using: Project Reactor
Knoldus Inc.
 
PPTX
Spring Framework
tola99
 
PPTX
Spring Webflux
Carlos E. Salazar
 
PDF
Domain-Driven Design with ASP.NET MVC
Steven Smith
 
PPTX
Presentation on middle marshyangdi hydropower project
Sudarshan Pandey
 
PDF
20220716_만들면서 느껴보는 POP
Chiwon Song
 
PDF
Introduction to Spring webflux
Knoldus Inc.
 
PDF
Compose Camp - Jetpack Compose for Android Developers Introduction Session De...
JassGroup TICS
 
PPTX
ReactJs presentation
nishasowdri
 
PDF
칸반(Kanban)
영기 김
 
PDF
LoadRunner walkthrough
Bhuvaneswari Subramani
 
PDF
Jetpack Compose a new way to implement UI on Android
Nelson Glauber Leal
 
PDF
LLM with Java.pdf
Yugo Sakamoto
 
PPTX
Tariff determination for hydro power plant
Krishnakumar R. Vasudevan
 
PDF
Composable and streamable Play apps
Yevgeniy Brikman
 
PDF
Spring Framework - MVC
Dzmitry Naskou
 
Treinamento: como usar o JMeter, interpretar resultados e otimizar a execução
Beatriz Makiyama Celestino
 
Cucumber presenation
Oussama BEN WAFI
 
Understanding Reactive Programming
Andres Almiray
 
Microservices with Spring 5 Webflux - jProfessionals
Trayan Iliev
 
Reactive Programming In Java Using: Project Reactor
Knoldus Inc.
 
Spring Framework
tola99
 
Spring Webflux
Carlos E. Salazar
 
Domain-Driven Design with ASP.NET MVC
Steven Smith
 
Presentation on middle marshyangdi hydropower project
Sudarshan Pandey
 
20220716_만들면서 느껴보는 POP
Chiwon Song
 
Introduction to Spring webflux
Knoldus Inc.
 
Compose Camp - Jetpack Compose for Android Developers Introduction Session De...
JassGroup TICS
 
ReactJs presentation
nishasowdri
 
칸반(Kanban)
영기 김
 
LoadRunner walkthrough
Bhuvaneswari Subramani
 
Jetpack Compose a new way to implement UI on Android
Nelson Glauber Leal
 
LLM with Java.pdf
Yugo Sakamoto
 
Tariff determination for hydro power plant
Krishnakumar R. Vasudevan
 
Composable and streamable Play apps
Yevgeniy Brikman
 
Spring Framework - MVC
Dzmitry Naskou
 

Viewers also liked (20)

PPTX
Avoiding callback hell in Node js using promises
Ankit Agarwal
 
PPTX
Promises, Promises
Domenic Denicola
 
PDF
Understanding Asynchronous JavaScript
jnewmanux
 
PPTX
Avoiding Callback Hell with Async.js
cacois
 
PPTX
JavaScript Promises
L&T Technology Services Limited
 
PPTX
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
PDF
Beyond the Callback: Yield Control with Javascript Generators
Darren Cruse
 
PDF
jQuery Essentials
Bedis ElAchèche
 
PPT
Ambient Media Worldwide Ltd Jd Lr
Johnnboy75
 
PPTX
JavaScript closures
Horky Chen
 
PPT
Wow! closure in_javascript
cnlangzi
 
PDF
Callback Function
Roland San Nicolas
 
PDF
JavaScript closures
Dumitru Ungureanu
 
PPTX
javascript function & closure
Hika Maeng
 
PDF
Asynchronous JavaScript and Promises
Senthil Kumar
 
PPTX
Closure
Xiaojun REN
 
PDF
#7 "Многообещающий JavaScript – Promises" Денис Речкунов
JSib
 
PPTX
App cache vs localStorage
senthil_hi
 
PDF
Promise pattern
Sebastiaan Deckers
 
PDF
The Future starts with a Promise
Alexandru Nedelcu
 
Avoiding callback hell in Node js using promises
Ankit Agarwal
 
Promises, Promises
Domenic Denicola
 
Understanding Asynchronous JavaScript
jnewmanux
 
Avoiding Callback Hell with Async.js
cacois
 
JavaScript Promises
L&T Technology Services Limited
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
Beyond the Callback: Yield Control with Javascript Generators
Darren Cruse
 
jQuery Essentials
Bedis ElAchèche
 
Ambient Media Worldwide Ltd Jd Lr
Johnnboy75
 
JavaScript closures
Horky Chen
 
Wow! closure in_javascript
cnlangzi
 
Callback Function
Roland San Nicolas
 
JavaScript closures
Dumitru Ungureanu
 
javascript function & closure
Hika Maeng
 
Asynchronous JavaScript and Promises
Senthil Kumar
 
Closure
Xiaojun REN
 
#7 "Многообещающий JavaScript – Promises" Денис Речкунов
JSib
 
App cache vs localStorage
senthil_hi
 
Promise pattern
Sebastiaan Deckers
 
The Future starts with a Promise
Alexandru Nedelcu
 
Ad

Similar to Callbacks, promises, generators - asynchronous javascript (20)

PPT
You promise?
IT Weekend
 
PDF
Better react/redux apps using redux-saga
Younes (omar) Meliani
 
PDF
Promises - Asynchronous Control Flow
Henrique Barcelos
 
PDF
Angular promises and http
Alexe Bogdan
 
PDF
Unit Testing Express Middleware
Morris Singer
 
PDF
Workshop 5: JavaScript testing
Visual Engineering
 
PDF
$q and Promises in AngularJS
a_sharif
 
PDF
Promises & limbo
Sylvain Faucherand
 
PDF
Testing Ember Apps: Managing Dependency
Matthew Beale
 
PDF
Promises are so passé - Tim Perry - Codemotion Milan 2016
Codemotion
 
PPTX
AngularJS, More Than Directives !
Gaurav Behere
 
PDF
Sane Async Patterns
TrevorBurnham
 
PDF
Fundamental JavaScript [UTC, March 2014]
Aaron Gustafson
 
PDF
Chaining and function composition with lodash / underscore
Nicolas Carlo
 
PDF
Node js
LearningTech
 
PDF
Asynchronous programming done right - Node.js
Piotr Pelczar
 
PDF
Javascript: the important bits
Chris Saylor
 
PPTX
Java script for web developer
Chalermpon Areepong
 
PDF
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays
 
PDF
New improvements for web developers - frontend.fi, Helsinki
Robert Nyman
 
You promise?
IT Weekend
 
Better react/redux apps using redux-saga
Younes (omar) Meliani
 
Promises - Asynchronous Control Flow
Henrique Barcelos
 
Angular promises and http
Alexe Bogdan
 
Unit Testing Express Middleware
Morris Singer
 
Workshop 5: JavaScript testing
Visual Engineering
 
$q and Promises in AngularJS
a_sharif
 
Promises & limbo
Sylvain Faucherand
 
Testing Ember Apps: Managing Dependency
Matthew Beale
 
Promises are so passé - Tim Perry - Codemotion Milan 2016
Codemotion
 
AngularJS, More Than Directives !
Gaurav Behere
 
Sane Async Patterns
TrevorBurnham
 
Fundamental JavaScript [UTC, March 2014]
Aaron Gustafson
 
Chaining and function composition with lodash / underscore
Nicolas Carlo
 
Node js
LearningTech
 
Asynchronous programming done right - Node.js
Piotr Pelczar
 
Javascript: the important bits
Chris Saylor
 
Java script for web developer
Chalermpon Areepong
 
FrontDays #3. Иван Федяев, Эволюция JavaScript. Обзор нововведений ECMAScript 6
FrontDays
 
New improvements for web developers - frontend.fi, Helsinki
Robert Nyman
 
Ad

Recently uploaded (20)

PDF
Geothermal Heat Pump ppt-SHRESTH S KOKNE
SHRESTHKOKNE
 
PDF
CAD-CAM U-1 Combined Notes_57761226_2025_04_22_14_40.pdf
shailendrapratap2002
 
PDF
7.2 Physical Layer.pdf123456789101112123
MinaMolky
 
PPTX
Introduction to Fluid and Thermal Engineering
Avesahemad Husainy
 
PDF
All chapters of Strength of materials.ppt
girmabiniyam1234
 
PPTX
00-ClimateChangeImpactCIAProcess_PPTon23.12.2024-ByDr.VijayanGurumurthyIyer1....
praz3
 
PPTX
ETP Presentation(1000m3 Small ETP For Power Plant and industry
MD Azharul Islam
 
PDF
NOISE CONTROL ppt - SHRESTH SUDHIR KOKNE
SHRESTHKOKNE
 
PDF
MRI Tool Kit E2I0500BC Plus Presentation
Ing. Ph. J. Daum GmbH & Co. KG
 
PDF
Non Text Magic Studio Magic Design for Presentations L&P.pdf
rajpal7872
 
PDF
Machine Learning All topics Covers In This Single Slides
AmritTiwari19
 
PPTX
Precedence and Associativity in C prog. language
Mahendra Dheer
 
PDF
Jual GPS Geodetik CHCNAV i93 IMU-RTK Lanjutan dengan Survei Visual
Budi Minds
 
PDF
CFM 56-7B - Engine General Familiarization. PDF
Gianluca Foro
 
PDF
Natural Language processing and web deigning notes
AnithaSakthivel3
 
PPTX
MULTI LEVEL DATA TRACKING USING COOJA.pptx
dollysharma12ab
 
PPT
IISM Presentation.ppt Construction safety
lovingrkn
 
PPTX
Basics of Auto Computer Aided Drafting .pptx
Krunal Thanki
 
PPTX
FUNDAMENTALS OF ELECTRIC VEHICLES UNIT-1
MikkiliSuresh
 
PPTX
Online Cab Booking and Management System.pptx
diptipaneri80
 
Geothermal Heat Pump ppt-SHRESTH S KOKNE
SHRESTHKOKNE
 
CAD-CAM U-1 Combined Notes_57761226_2025_04_22_14_40.pdf
shailendrapratap2002
 
7.2 Physical Layer.pdf123456789101112123
MinaMolky
 
Introduction to Fluid and Thermal Engineering
Avesahemad Husainy
 
All chapters of Strength of materials.ppt
girmabiniyam1234
 
00-ClimateChangeImpactCIAProcess_PPTon23.12.2024-ByDr.VijayanGurumurthyIyer1....
praz3
 
ETP Presentation(1000m3 Small ETP For Power Plant and industry
MD Azharul Islam
 
NOISE CONTROL ppt - SHRESTH SUDHIR KOKNE
SHRESTHKOKNE
 
MRI Tool Kit E2I0500BC Plus Presentation
Ing. Ph. J. Daum GmbH & Co. KG
 
Non Text Magic Studio Magic Design for Presentations L&P.pdf
rajpal7872
 
Machine Learning All topics Covers In This Single Slides
AmritTiwari19
 
Precedence and Associativity in C prog. language
Mahendra Dheer
 
Jual GPS Geodetik CHCNAV i93 IMU-RTK Lanjutan dengan Survei Visual
Budi Minds
 
CFM 56-7B - Engine General Familiarization. PDF
Gianluca Foro
 
Natural Language processing and web deigning notes
AnithaSakthivel3
 
MULTI LEVEL DATA TRACKING USING COOJA.pptx
dollysharma12ab
 
IISM Presentation.ppt Construction safety
lovingrkn
 
Basics of Auto Computer Aided Drafting .pptx
Krunal Thanki
 
FUNDAMENTALS OF ELECTRIC VEHICLES UNIT-1
MikkiliSuresh
 
Online Cab Booking and Management System.pptx
diptipaneri80
 

Callbacks, promises, generators - asynchronous javascript

  • 2. callbacks, promises, generators Asynchronous code ! var result = asyncFunction(); // you won't get result immediately typeof result === 'undefined'; // true
  • 3. callbacks, promises, generators Callbacks asyncFunction(function() { // i’ll be called when the execution ends ! // where is the result? // there was any error? });
  • 4. callbacks, promises, generators Callbacks - Node.js way - callback-based functions var asyncFunction = function(args, ..., callback) { setTimeout(function() { ! // "returning" result callback(null, {tasty: 'sandwich'}); ! // or // "throwing" errors callback(new Error('Error message')); }, 50); }; ! asyncFunction(function(error, result, result1 ...) { if (error) { // handle error return; // don't forget about this! } // handle result });
  • 5. callbacks, promises, generators Callbacks - Own patterns - DON’t do it var asyncFunction = function(callback) { setTimeout(function() { callback({tasty: 'sandwich'}); }, 50); }; ! asyncFunction(function(result) { result; // {tasty: 'sandwich'} ! // but... what about errors? });
  • 6. callbacks, promises, generators Callbacks - Own patterns - DON’t do it
  • 7. callbacks, promises, generators Callbacks - Callback-based function
  • 9. callbacks, promises, generators Callbacks - Callback hell var fetchResultFromDb = function(callback) { db.fetch(function(error, result) { if (error) { callback(error); return; } ! serializeResult(result, function(error, result) { if (error) { callback(error); return; } callback(null, result); // finally! }); }); }; ! fetchResultFromDb(function(error, result) { if (error) { console.error(error); return; } ! result; // end result });
  • 11. callbacks, promises, generators Callbacks - Callback hell var function1 = function (callback) { function2(function(error, result) { if (error) { callback(error); return; } ! function3(result, function(error, result) { if (error) { callback(error); return; } ! function4(result, function(error, result) { if (error) { callback(error); return; } ! function5(result, function(error, result) { // ... }); }); }); }); };
  • 12. callbacks, promises, generators Callbacks - Callback hell - map - var map = function(input, callback) { var results = [], handleIterationResult = function(error, result) { if (error) { callback(error); return; } results.push(result); if (results.length === input.length) { callback(null, results); } }; input.forEach(function(num) { sum(num, handleIterationResult); }); }; ! var sum = function(num, callback) { callback(null, num + num); }; ! map([1, 2, 3, 4, 5], function(error, result) { if (error) { console.error(error); return; }; result; // [2, 4, 6, 8, 10] }); DON’t do it
  • 15. callbacks, promises, generators Callbacks - Introducing async ASYNC by Caolan McMahon „Higher-order functions and common patterns for asynchronous code”
  • 16. callbacks, promises, generators Callbacks - async waterfall async.waterfall([ function(callback){ callback(null, 'one', 'two'); }, function(arg1, arg2, callback){ arg1 === 'one'; // true arg === 'two'; // true callback(null, 'three'); }, function(arg1, callback){ arg1 === 'three'; // true callback(null, 'done'); } ], function (err, result) { result === 'done'; // true });
  • 17. callbacks, promises, generators Callbacks - async waterfall var fetchResultFromDb = function(callback) { async.waterfall([ db.fetch.bind(db), // to preserve function context serializeResult ], callback); }; ! fetchResultFromDb(function(error, result) { if (error) { console.error(error); return; } result; });
  • 18. callbacks, promises, generators Callbacks - async MAP var sum = function(num, callback) { callback(null, num + num); }; ! async.map([1, 2, 3, 4, 5], sum, function(error, result) { if (error) { console.error(error); return; } result; // [2, 4, 6, 8, 10] });
  • 20. callbacks, promises, generators Callbacks - asynC Collections each, map, filter, reduce, some ... Control flow series, parallel, waterfall, compose ...
  • 21. callbacks, promises, generators Promises According to Promises/A+ specification „promise is an object or function with a then method whose behavior conforms to this specification (...) [and] represents the eventual result of an asynchronous operation„ More specs http://wiki.commonjs.org/wiki/Promises
  • 22. callbacks, promises, generators Promises var promise = promisedFunction(); ! typeof promise !== 'undefined'; // true 'then' in promise; // true
  • 23. callbacks, promises, generators Promises - introducing Q Q by Kris Kowal „A tool for making and composing asynchronous promises in JavaScript”
  • 24. callbacks, promises, generators Promises - Promise-based function var promisedFunction = function() { var defer = Q.defer(); ! setTimeout(function() { ! // REJECTING // "throwing" error defer.reject(new Error('Error message')); ! // or // FULFILLING // "returning" result - defer.resolve({tasty: 'sandwich'}); ! }, 50); ! return defer.promise; // remember to always return a promise };
  • 25. callbacks, promises, generators Promises - basic usage ! var promise = promisedFunction(); ! promise.then(function(result) { // handle result }, function(error) { // handle error }); ! // more "listeners" promise.then(onSuccess, onError); // ...
  • 26. callbacks, promises, generators Promises - fulfilling by promise Q.fcall(function() { var defer = Q.defer(); setTimeout(function() { defer.resolve(['tasty']); }, 50); return defer.promise; }) .then(function(result) { var defer = Q.defer(); setTimeout(function() { defer.resolve(result.concat(['sandwich'])); }, 50); return defer.promise; }) .then(function(result) { result; // ['tasty', 'sandwich'] }, function(error) { // handling error }); Remember waterfall pattern from async library?
  • 27. callbacks, promises, generators Promises - fulfilling by promise
  • 28. callbacks, promises, generators Promises - COnverting callback-based functions var callbackBasedFunction = function(callback) { setTimeout(function() { callback(null, {tasty: 'sandwich'}); }, 50); }; ! var promiseBasedFunction = Q.denodeify(callbackBasedFunction); ! promiseBasedFunction() .then(function(result) { result; // {tasty: 'sandwich'} });
  • 29. callbacks, promises, generators Promises - previous waterfall example var fetchFromDb = function() { return Q.ninvoke(db, 'fetch') .then(Q.denodeify(serializeResults)); }; ! fetchFromDb() .then(function(result) { result; }); You have to convert each callback-based function into promise-based for chaining
  • 30. callbacks, promises, generators Promises - MAP var promisedSum = Q.denodeify(sum); ! var promises = [1, 2, 3, 4, 5].map(function(num) { return promisedSum(num); }); ! Q.all(promises).then(function(result) { console.log(result); }); Q.all is a custom Q library function. Not in spec.
  • 31. callbacks, promises, generators Promises - compatibility https://github.com/kriskowal/q#the-middle „When working with promises provided by other libraries, you should convert it to a Q promise. Not all promise libraries make the same guarantees as Q and certainly don’t provide all of the same methods.”
  • 32. callbacks, promises, generators Promises AND NPM packages Always expose your package API as callback-based functions! It’s a standard
  • 34. callbacks, promises, generators Generators - ES6 feature var generatorFunction = function*() { // note asterisk var value = yield 1; // waits here for „next” call value; // {tasty: 'sandwich' } yield 2; }; ! var gen = generatorFunction(); gen.next(); // { value: 1, done: false } gen.next({tasty: 'sandwich'}); // { value: 2, done: false } gen.next(); // { value: undefined, done: true }
  • 36. callbacks, promises, generators Generators + promise var promisedStep = Q.denodeify(function(callback) { setTimeout(function() { callback(null, {tasty: 'sandwich'}); }, 50); }); ! var generatorFunction = function*() { var result = yield promisedStep; result; // {tasty: 'sandwich'} }; ! var gen = generatorFunction(); var result = gen.next(); result.value() .then(function(result) { gen.next(result); }, function(error) { gen.throw(error); });
  • 37. callbacks, promises, generators Generators + Exceptions var promisedStep = Q.denodeify(function(callback) { setTimeout(function() { callback(new Error('No butter!')); }, 50); }); ! var generatorFunction = function*() { try { var result = yield promisedStep; } catch (error) { error; // [Error: No butter!] } }; ! var gen = generatorFunction(); ! var result = gen.next(); result.value() .then(function(result) { gen.next(result); }, function(error) { gen.throw(error); });
  • 39. callbacks, promises, generators Generators - introducing CO CO by TJ Holowaychuk „The ultimate generator based flow-control goodness for nodejs (supports thunks, promises, etc)”
  • 40. callbacks, promises, generators Generators - CO var fetchResultFromDb = function*() { var records = yield thunkify(db.fetch.bind(db))(); return yield thunkify(serializeResults)(records); }; ! co(function*() { var result = yield fetchResultFromDb; })();
  • 41. callbacks, promises, generators Generators - THUNK var asyncFunction = function(arg1, arg2, calback) { setTimeout(function() { callback(null, {tasty: 'sandwich with '+arg1+' and '+arg2}) }, 50); }; co(function*() { yield asyncFunction; // what about arguments? yield asyncFunction.bind(undefined, 'butter', 'cheese'); })();
  • 42. callbacks, promises, generators Generators - THUNK var thunkifiedAsyncFunction = thunkify(asyncFunction); // fn(args, ..., callback) asyncFunction('butter', 'cheese', function(err, result) { }); ! // transformed into // fn(args)(callback) thunkifiedAsyncFunction('butter', 'cheese')(function(err, result) { });
  • 43. callbacks, promises, generators Generators - co - map var thunkifiedSum = thunkify(sum); co(function*() { var result = yield [1, 2, 3, 4, 5].map(function(num) { return thunkifiedSum(num); }); ! result; // [ 2, 4, 6, 8, 10 ] })();
  • 45. callbacks, promises, generators Generators - NOT YET! Supported by firefox and chrome (disabled by default) Node.js 0.11.* - not stable yet
  • 46. callbacks, promises, generators CONCLUSIONs You need a library for asynchronous code Use callback-based functions for public API Pick solution that is fine for you and your team
  • 47. callbacks, promises, generators More informations Promises/A+ Performance Hits You Should Be Aware Of https://github.com/substack/node-seq http://wiki.commonjs.org/wiki/Promises
  • 49. callbacks, promises, generators Font „Blue Highway” from http://typodermicfonts.com/ Thanks!