Async js - Nemetschek Presentaion @ HackBulgaria

20

Click here to load reader

description

This is presentation from Nemetschek Bulgaria - one of the partners of HackBulgaria's JavaScript course. The topic is Async JS -How does the event loop in JS works and what are the benefits of the Promises.

Transcript of Async js - Nemetschek Presentaion @ HackBulgaria

Page 1: Async js - Nemetschek Presentaion @ HackBulgaria

Async JavaScript & Promises/A+Martin Dimitrov

July 2014

Page 2: Async js - Nemetschek Presentaion @ HackBulgaria

About meMartin Dimitrov

[email protected] Developer Web Technologies, Nemetschek Bulgaria

Page 3: Async js - Nemetschek Presentaion @ HackBulgaria

JavaScript

● The single language available in Modern Web Browsers.● Full stack Web programming with Node.js● Single-threaded & Event-driven asynchronous processing● Jeff Atwood Atwood’s law:

“Any application that can be written in JavaScript will eventually be written in JavaScript.”

Functions & Callbacks

● Functions are first class citizens in JavaScript● Functions can accept other functions as parameters and call

them either synchronously or asynchronously.

Page 4: Async js - Nemetschek Presentaion @ HackBulgaria

Callbacks example

$('#saveButton').on('click', function(){ $(this).closest('form').submit();});

function readJSON(filename, callback) { fs.readFile(filename, 'utf8', function(err, res) { if (err) return callback(err); try { res = JSON.parse(res); } catch (ex) { return callback(ex); } callback(null, res); });} Pyramid of Doom

step1(function(result1) { step2(function(result2) { step3(function(result3) { // and so on... }); });});

Page 5: Async js - Nemetschek Presentaion @ HackBulgaria

Callback Hell

fs.readdir(source, function(err, files) { if (err) { console.log('Error finding files: ' + err) } else { files.forEach(function(filename, fileIndex) { console.log(filename) gm(source + filename).size(function(err, values) { if (err) { console.log('Error identifying file size: ' + err) } else { console.log(filename + ' : ' + values) aspect = (values.width / values.height) widths.forEach(function(width, widthIndex) { height = Math.round(width / aspect) console.log('resizing ' + filename + 'to ' + height + 'x' + height) this.resize(width, height).write(destination + 'w' + width + '_' + filename, function(err) { if (err) console.log('Error writing file: ' + err) }) }.bind(this)) } }) }) }});

Page 6: Async js - Nemetschek Presentaion @ HackBulgaria

Example 1http://codepen.io/sachmata/pen/Hoygz/

for (var i = 1; i <= 3; i++) { setTimeout(function() { console.log('async: ' + i); }, 0); console.log('sync: ' + i);}

Example 2http://codepen.io/sachmata/pen/GrmFE

var start = Date.now();setTimeout(function() { var end = Date.now(); console.log('Time elapsed:', end - start, 'ms');}, 500);

while (Date.now() - start < 1000) { // do nothing};

Page 7: Async js - Nemetschek Presentaion @ HackBulgaria
Page 8: Async js - Nemetschek Presentaion @ HackBulgaria

Types of Async Functions

● I/O Functions (XMLHttpRequest)● Timing Functions (setTimeout, setInterval, setImmediate,

requestAnimationFrame)● Sometimes-Async Functions (caching)

Error handling in Async Functions

● throw from callback● try/catch over async function does not work !

setTimeout(function A() { setTimeout(function B() { setTimeout(function C() { throw new Error( 'Something terrible has happened!'); }, 0); }, 0);}, 0);

Error: Something terrible has happened!at Timer.C (/AsyncJS/nestedErrors.js:4:13)

try { setTimeout(function() { throw new Error( 'Catch me if you can!'); }, 0);} catch (e) { console.error(e);}

Page 9: Async js - Nemetschek Presentaion @ HackBulgaria

What is a promise? http://www.promisejs.org/

The core idea behind promises is that a promise represents the result of an asynchronous operation. A promise is in one of three different states:

● pending - The initial state of a promise.● fulfilled - The state of a promise representing a successful operation.● rejected - The state of a promise representing a failed operation.

Once a promise is fulfilled or rejected, it is immutable (i.e. it can never change again).

Specification Promises/A+ http://promisesaplus.com/ - (thenable) defines only 'then' method

promise.then(function(result) { console.log(result); // "Stuff worked!"}, function(err) { console.log(err); // Error: "It broke"});

Page 10: Async js - Nemetschek Presentaion @ HackBulgaria

Browser support● Q● when● WinJS● RSVP.JS● jQuery 1.8+ (Deferred object) ! Not Promise/A+ compliant !● Conformant Implementations of Promises/A+ / Test suite

https://github.com/promises-aplus/promises-spec/blob/master/implementations.md● ECMAScript 6

Page 11: Async js - Nemetschek Presentaion @ HackBulgaria

jQuery Example (probably you have already used promises - new ajax module)

// Assign handlers immediately after making the request,// and remember the jqxhr object for this requestvar jqxhr = $.get("example.php", function() { console.log("success");}).done(function() { console.log("second success");}).fail(function() { console.log("error");}).always(function() { console.log("finished");});

// Perform other work here ...

// Set another completion function for the request abovejqxhr.always(function() { console.log("second finished");});

Page 12: Async js - Nemetschek Presentaion @ HackBulgaria

Creating jQuery promiseOption 1function readJSON(filename) { var task = $.Deferred(); fs.readFile(filename, 'utf8', function(err, res) { if (err) return task.reject(err); try { res = JSON.parse(res); } catch (ex) { task.reject(err); } task.resolve(res); }); return task.promise();}

Option 2function readJSON(filename) { return $.Deferred(function(task) { fs.readFile(filename, 'utf8', function(err, res) { if (err) return task.reject(err); try { res = JSON.parse(res); } catch (ex) { task.reject(err); } task.resolve(res); }); }).promise();}

Page 13: Async js - Nemetschek Presentaion @ HackBulgaria

Other Deferreds in jQuery API

Animationsvar dialogPromise = $('#dialog').fadeIn().promise();dialogPromise.done(afterDialogShown);

Document ready$(onReady);$(document).ready(onReady);$.ready.promise().done(onReady);

Page 14: Async js - Nemetschek Presentaion @ HackBulgaria

What we get from promises?

● Invocation chaining/combining● Error propagation● Common error handling● Common success handling● Progress notification (if supported)● Wrap other async solutions

You're Missing the Point of Promises !http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

Page 15: Async js - Nemetschek Presentaion @ HackBulgaria

Chaining Promises

getJSON("/posts.json").then(function(json) { return json.post;}).then(function(post) { // proceed});

ErrorsgetJSON("/posts.json").then(function(posts) { // }).catch(function(error) { // since no rejection handler was passed to the // first `.then`, the error propagates.});

getJSON("/post/1.json").then(function(post) { return getJSON(post.commentURL);}).then(function(comments) { // proceed with access to posts and comments}).catch(function(error) { // handle errors in either of the two requests});

Page 16: Async js - Nemetschek Presentaion @ HackBulgaria

Promise with Exception

var userPromise = getUser().then(function(user) { if (user === null) { throw new Error('user is null'); } return user;}).then(function(user){...}, function(err){...}).done();

Beware of unhandled exceptions/rejections when no reject callback is registered! Unhandled Exceptions in synchronous code will hit the top of the stack, here might sink silently. Use 'done' method at the end of Promises chain to signal that any unhandled exceptions should explode.

Page 17: Async js - Nemetschek Presentaion @ HackBulgaria

try/catch/finally

startSpinner();getUser('martin') .then(getProfile) .then(showProfile) //.then(errorThrowingFunction) .catch(displayError) .finally(stopSpinner) .done();

Q.all / RSVP.all / $.when / WinJS.Promise

var promise = Q.all([getUser(), getCompany()]).then(function(results) {…});var promise = $.when(getUser(), getCompany()).then(function(user, company) {…})

var promise = WinJS.Promise.join({ user: getUser(), company: getCompany()}).then(function(data) {…}).done();

var promise = WinJS.Promise.any([ getUser(), getCompany()]).then(function(winner) {…}).done();

Page 18: Async js - Nemetschek Presentaion @ HackBulgaria

Theoreticaly Promises/A+ compliant promises from different implementations can be mixed, but jQuery promises are not compliant – assimilate as soon as possible.

var realPromise = when(jQueryPromise);

Promises/A+ Performance Hits You Should Be Aware Ofhttp://thanpol.as/javascript/promises-a-performance-hits-you-should-be-aware-of/

Page 19: Async js - Nemetschek Presentaion @ HackBulgaria

Recommended reads

Async JavaScript: Build More Responsive Apps with Less Codeby Trevor Burnham

JavaScript: The Good Partsby Douglas Crockford

Page 20: Async js - Nemetschek Presentaion @ HackBulgaria

Thank you. Questions?