Slide 1

Slide 1 text

I love async... but I can’t code like this Friday, August 10, 12

Slide 2

Slide 2 text

Pau Ramon @masylum Friday, August 10, 12

Slide 3

Slide 3 text

What does “asynchrony” mean? Whenever code evaluation will not happen synchronously Friday, August 10, 12

Slide 4

Slide 4 text

Synchronous code evaluation 1 - function printL() { 3 - console.log('L'); } 2 - printL(); 4 - console.log('O'); 5 - console.log('L'); 6 - End, the event loop is empty: Exit Friday, August 10, 12

Slide 5

Slide 5 text

Asynchronous code evaluation 1 - setTimeout(function printO() { ? - console.log('O'); }, Math.random * 1000); 2 - setTimeout(function printL() { ? - console.log('L'); }, Math.random * 1000); 3 - console.log('L'); 4 - End, `printL` and `printO` in the EL 7 - End, `printL` or `printO` in the EL 8 - End, the event loop is empty: Exit Friday, August 10, 12

Slide 6

Slide 6 text

Problem? • Order may matter • Code may get evaluated or not • Your program is not under your control • ... you name it Friday, August 10, 12

Slide 7

Slide 7 text

Do n asynchronous calls, one after the other. Chain pattern Friday, August 10, 12

Slide 8

Slide 8 text

Example: Get A from db then use A.id to get B from db then use B.id to get C A B C Chain pattern Friday, August 10, 12

Slide 9

Slide 9 text

Chain pattern setTimeout(function A() { console.log('A'); setTimeout(function B() { console.log('B'); setTimeout(function C() { console.log('C'); }, 10); }, 250); }, 100); Friday, August 10, 12

Slide 10

Slide 10 text

Chain pattern Friday, August 10, 12

Slide 11

Slide 11 text

Imperative paradigm == How Do A, then do B, then you get C Friday, August 10, 12

Slide 12

Slide 12 text

Imperative paradigm == How Example: To get an average you have to: Get the size of your dataset, then add your inputs and divide both results. Friday, August 10, 12

Slide 13

Slide 13 text

Functional paradigm Friday, August 10, 12

Slide 14

Slide 14 text

Functional paradigm == Wat C is what you get from B once you did A Friday, August 10, 12

Slide 15

Slide 15 text

Functional paradigm == Wat Example: An average is: What you get after diving your added inputs by the dataset size Friday, August 10, 12

Slide 16

Slide 16 text

Thinking functional is kind of backwards! Friday, August 10, 12

Slide 17

Slide 17 text

Asynchronous code is not linear, so define your problems in a functional way if possible. Friday, August 10, 12

Slide 18

Slide 18 text

Chain pattern function C() { console.log('C'); } function B() { console.log('B'); setTimeout(C, 10); } function A() { console.log('A'); setTimeout(B, 250); } setTimeout(A, 100); Friday, August 10, 12

Slide 19

Slide 19 text

Chain pattern var Step = require('step'); Step(function A() { console.log('A'); setTimeout(this, 100); }, function B() { console.log('B'); setTimeout(this, 250); }, function C() { console.log('C'); setTimeout(this, 10); }); Friday, August 10, 12

Slide 20

Slide 20 text

Chain pattern var async = require('async'); async.series([function A() { console.log('A'); setTimeout(this, 100); }, function B() { console.log('B'); setTimeout(this, 250); }, function C() { console.log('C'); setTimeout(this, 10); }]); Friday, August 10, 12

Slide 21

Slide 21 text

Chain pattern // I WANT A BETTER API! setTimeout(Chainer(function A() { console.log('A'); }), 100); setTimeout(Chainer(function B() { console.log('B'); }), 250); setTimeout(Chainer(function C() { console.log('C'); }), 10); Friday, August 10, 12

Slide 22

Slide 22 text

Chain pattern var Chainer = function (fn) { (Chainer.functions = Chainer.functions || []).push(fn); return function next() { fn['arguments'] = arguments; fn.done = true; (function run() { if (Chainer.functions.length && Chainer.functions[0].done) { var el = Chainer.functions.shift(); el.apply(el, el['arguments']); run(); } }()); }; }; Friday, August 10, 12

Slide 23

Slide 23 text

Chain pattern Friday, August 10, 12

Slide 24

Slide 24 text

Do n asynchronous calls, process them, and trigger a callback once all are evaluated. Parallel pattern Friday, August 10, 12

Slide 25

Slide 25 text

Parallel pattern var count = 2; function callback() { count--; if (count === 0) console.log('DONE!'); } setTimeout(function A() { console.log('A'); callback(); }, 100); setTimeout(function B() { console.log('B'); callback(); }, 250); Friday, August 10, 12

Slide 26

Slide 26 text

Parallel pattern Step(function parallel() { var self = this; setTimeout(function A() { console.log(’A’); self.parallel(); // FFFUUU API }, 100); setTimeout(function B() { console.log(’B’); self.parallel(); // FFFUUU API }, 250); }, function callback() { console.log('DONE'); }); Friday, August 10, 12

Slide 27

Slide 27 text

Parallel pattern async.parallel([function(){ setTimeout(function A(callback) { console.log(’A’); callback(); }, 100); setTimeout(function B(callback) { console.log(’B’); callback(); }, 250); }], function callback() { console.log('DONE'); }); Friday, August 10, 12

Slide 28

Slide 28 text

Parallel pattern setTimeout(parallel(function A() { console.log('A'); }), 100); setTimeout(parallel(function B() { console.log('B'); }), 250); parallel.callback = function () { console.log('DONE!'); }; Friday, August 10, 12

Slide 29

Slide 29 text

Parallel pattern var parallel = function () { var count = 0; return function parallel(fn) { count++; fn = fn || function () {}; return function () { fn.apply(fn, arguments); if (!--count) { parallel.callback(); } }; }; }; Friday, August 10, 12

Slide 30

Slide 30 text

Use named functions, always. Try to create the API you need. Handle errors always. Think functional! My advice Friday, August 10, 12

Slide 31

Slide 31 text

That’s all folks! Friday, August 10, 12