Slide 1

Slide 1 text

Asynchronous JavaScript: Events, Callbacks & Promises Lee Boonstra @ladysign

Slide 2

Slide 2 text

Which value will be alerted? var  i  =  5;   function  calc(num){   setTimeout(function(){     i  =  i  *  0;     return  i;   },  3000);                                       i  =  i  *  5;   }   calc(5);   alert(i); Answer? A) 5 B) 25 C) 0

Slide 3

Slide 3 text

JavaScript is Single Threaded • Code executes from top to bottom • Right after each other • 2 bits of code cannot run at the same time

Slide 4

Slide 4 text

The Event Loop • Queue of callback functions • JS engine won’t start processing after the code after the method has been executed

Slide 5

Slide 5 text

So, how to deal with async code? • Events • Callbacks • Promises

Slide 6

Slide 6 text

Events

Slide 7

Slide 7 text

Observer Pattern • Events are a solution to communicate when async callbacks finish executing. • Objects can publish events that other objects can listen for. • Ext.mixin.Observable

Slide 8

Slide 8 text

Types of events • User Events • System Events • Life Cycle Events button.addListener('tap',           function(c)  {          //do  something   }); User Event store.on('load',   function(store)  {          //do  something   }); System Event grid.on('afterrender',   function(c)  {        //do  something   }); Life Cycle Event

Slide 9

Slide 9 text

View ViewController Ext.define(‘MyApp.view.MyViewController’,   extend:  ‘Ext.app.ViewController’,   alias:  'controller.myviewcontroller',   onAfterRender:  function(){   //do  something…   }   … ..   controller:  ‘myviewcontroller’,   listeners:  {     ‘tap’  :  ‘onButtonTap’,       ‘afterrender':‘onAfterRender’   }   MVVM Listeners

Slide 10

Slide 10 text

“Events are great for things that can happen multiple times on the same object. With those events you don't really care about what happened before you attached the listener. But when it comes to asynchronous methods which have on success or on failure behavior, you rather want to use callbacks.”

Slide 11

Slide 11 text

Callbacks

Slide 12

Slide 12 text

Callback • Commonly used in asynchronous operations • When you call a function, pass in another function as argument

Slide 13

Slide 13 text

Example VC

Slide 14

Slide 14 text

Example Ext.Ajax.request({            url:  'feed.json',            success:  function(response,  opts)  {                  //doSomething()            },            failure:  function(response,  opts)  {                  //doSomething()            }    });

Slide 15

Slide 15 text

Example mystore.sync({   success:  function(batch,  o){  },   failure:  function(batch,  o){  },   callback:  function(batch,  o){  }   });

Slide 16

Slide 16 text

Tip! • Always use a loading spinner before you make your asynchronous call. • Never forget to clear the spinner, on success and failure.

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

Actor MainController user clicks play request selection from grid Grid SpotifyManager check if artist, track or album execute spotify return record make JsonP request play song / display error

Slide 19

Slide 19 text

Example VC //app/view/main/MainController.js   onPlay:  function(){    var  s  =  me.getViewModel().get(‘mygrid’).selection;    var  rec  =  s.getData();   //spinner    Engine.manager.Spotify.execSpotify(rec,  doneFnSpotify);   }

Slide 20

Slide 20 text

Callback horror • Unmaintainable / unreadable code due too many nested callbacks. • This is where JavaScript promises might become handy!

Slide 21

Slide 21 text

Promises

Slide 22

Slide 22 text

Promise • represents a “contract” for a value not securely known when the promise is created • an object or function with a “then” method whose behavior conforms to this specification. • A Promise can only succeed or fail once.

Slide 23

Slide 23 text

Promise states • fulfilled - the action relating to the promise succeeded • rejected - the action relating to the promise failed • pending - hasn't fulfilled or rejected yet • settled - has fulfilled or rejected

Slide 24

Slide 24 text

Thenable

Slide 25

Slide 25 text

The Promises A+ Spec This specification details the behavior of the then method, providing an interoperable base which all Promises/A+ conformant promise implementations can be depended on to provide. https://github.com/promises-aplus/promises-spec Ext JS 6 & Web Application Manager Promises are conform this spec!

Slide 26

Slide 26 text

An example of a Promise in JavaScript (ECMAScript 6): var  p  =  new  Promise(function(resolve,  reject)  {      //do  something();      if  (/*  everything  turned  out  fine  */)  {          resolve("OK");      }  else  {          reject(Error("Oh  no!"));      }   });  

Slide 27

Slide 27 text

How to use: p.then(function(result)  {      console.log(result);  //  "OK"   },  function(err)  {      console.log(err);  //  Error:  "Oh  no!"   });

Slide 28

Slide 28 text

Real world example

Slide 29

Slide 29 text

example of a callback, later I will rewrite it to use a promise var  done  =  function(err,  jobs){   res.render("myview",  {      user  :  req.user,        jobs:  jobs    });   };   getJobs  =  function(req,  done){       Job.findJobsOfUser(req.user._id,  function(err,  jobs){         if(err)  throw  err;         done(null,  jobs);       });   }   var  jobs  =  getJobs(req,  done);   This becomes callback horror, when I want to load more things, before rendering the page.

Slide 30

Slide 30 text

My solution, with the use of Promises… getJobs(req).then(function(jobs){          if(jobs){             //now  if  I  want  to  chain  this  with  more  calls             //i  just  run  the  res.render  call  last  (or  finally)            res.render("profile",  {                  user  :  req.user,                jobs:  jobs            });          }   },  function(error){          throw  error;   });

Slide 31

Slide 31 text

How to use: function  getJobs(req){       var  promise  =  new  Promise(function  (resolve,  reject)  {          Job.findJobsOfUser(req.user._id,  function  (err,  jobs)  {              if  (err)  reject(err);              else  resolve(jobs);          });       });             return  promise;   }

Slide 32

Slide 32 text

Browser Support

Slide 33

Slide 33 text

Promises in Ext JS • Ext JS 6 conforms Promises/A spec • Ext.Ajax is thenable. • Two forms: Ext.Promise() & Ext.Deferred() • Ext.Promise() - ECS6 wrapper • Ext.Deferred() - extra enhancements

Slide 34

Slide 34 text

Example Ext.Promise        requestUserName:  function(){             var  s  =  this.getStore();             return  new  Ext.Promise(function  (resolve,  reject)  {               s.load({           callback:  function(records,  operation,  success)  {                        if(success){                          if(records.length  >  0){                             resolve(records);                          }  else  {                             resolve(false);                          }                        }  else{                          reject(operation);                        }                }         });             });          }

Slide 35

Slide 35 text

Use Ext.Promise this.requestUserName().then(function(records){      if(records){          //do  something      }   },  function(error){      //throw  error   });

Slide 36

Slide 36 text

API methods • Promise.resolve(promiseOrAThenableValue) • Promise.reject(reason) • Promise.all(arrPromisesOrAThenableValues)

Slide 37

Slide 37 text

Instance methods • p.then(onFulfilled, onRejected, onProgress) • p.done() • p.cancel(reason) • p.always(onCompleted) • p.otherwise(onRejected)

Slide 38

Slide 38 text

Ext.Ajax built-in Promises Ext.Ajax.request({          url:  'feed.json',   }).then(function  (response)  {          //  use  response   });   //Ext.Ajax  extends  from  Ext.data.request.Base  

Slide 39

Slide 39 text

Ext.Ajax.request({          url:  'feed.json',   }).then(function(response)  {          //  use  response   }).always(function()  {        //  clean-­‐up  logic,  regardless  the  outcome   }).otherwise(function(reason){        //  handle  failure   });

Slide 40

Slide 40 text

Promises in Web Application Manager • Invoke API (to invoke other applications) • Device Camera API • Download Files API • File Collections & Secure Files APIs • Secure LocalStorage API • …

Slide 41

Slide 41 text

Actor SETTINGS user clicks username save request username from localstorage LOCAL STORAGE LASTFM MANAGER return results to the user request lastfm playlist return result if no records exist, add new, else edit return username

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

Deferreds

Slide 44

Slide 44 text

Deferreds • mechanism used to create new Promises with Ext JS 6 • Promises with additional features

Slide 45

Slide 45 text

Ext.Deferred doSomething:  function  ()  {            var  d  =  new  Ext.Deferred();  //create  the  Ext.Deferred  object            mystore.load({                    callback:  function  (records,  operation,  success)  {                            if  (success)  {                                    //  Use  "deferred"  to  drive  the  promise:                                    d.resolve(records);                            }                            else  {                                    //  Use  "deferred"  to  drive  the  promise:                                    d.reject("Error  loading  data.");                            }                    }            });            return  d.promise;    //  return  the  Promise  to  the  caller    }

Slide 46

Slide 46 text

Conclusion

Slide 47

Slide 47 text

Async JavaScript Events • Observer Pattern. Users, System and the LifeCycle can throw events, which are asynchronous. - There is no success or failure.

Slide 48

Slide 48 text

Async JavaScript Callbacks • Asynchronous JS. You pass a function in a function, deal with on success or failure.

Slide 49

Slide 49 text

Async JavaScript Promises • The result of a task, which can be fulfilled or rejected. Promises are chain-able.

Slide 50

Slide 50 text

Async JavaScript Ext.Deferred • Like Promises, but can be used as a base class, to let your methods return promises. • Sencha deferreds give additional extras

Slide 51

Slide 51 text

Resources • http://docs.sencha.com/extjs/6.0/6.0.0-classic/#!/api/Ext.Promise • http://docs.sencha.com/extjs/6.0/6.0.0-classic/#!/api/Ext.promise.Promise-method-then • http://docs.sencha.com/extjs/6.0/6.0.0-classic/#!/api/Ext.Deferred • https://github.com/promises-aplus/promises-spec • https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise

Slide 52

Slide 52 text

Questions?