Callbacks, promises, generators - asynchronous javascript

download Callbacks, promises, generators - asynchronous javascript

of 49

  • date post

    19-Aug-2014
  • Category

    Engineering

  • view

    4.492
  • download

    9

Embed Size (px)

description

How to manage asynchronous functions.

Transcript of Callbacks, promises, generators - asynchronous javascript

  • Callbacks, Promises, Generators ukasz Kuyski @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() { // ill 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 - DONt 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 - DONt 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] }); DONt 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, lter, reduce, some ... Control ow series, parallel, waterfall, compose ...
  • callbacks, promises, generators Promises According to Promises/A+ specication 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 dont provide all of the same methods.
  • callbacks, promises, generators Promises AND NPM packages Always expose your package API as callback-based functions! Its 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: 'san