Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Dealing with asynchronous JavaScript: Events, Callbacks & Promises/Deferreds

Lee Boonstra
September 07, 2015

Dealing with asynchronous JavaScript: Events, Callbacks & Promises/Deferreds

In real-world applications, we often deal with asynchronous code, for example to retrieve data from various systems. In this session, Lee Boonstra will talk about the various ways on how to deal with asynchronous bit of code. A talk about Events, Callbacks and the new Ext JS 6 Promises.

Lee Boonstra

September 07, 2015
Tweet

More Decks by Lee Boonstra

Other Decks in Technology

Transcript

  1. 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
  2. JavaScript is Single Threaded • Code executes from top to

    bottom • Right after each other • 2 bits of code cannot run at the same time
  3. The Event Loop • Queue of callback functions • JS

    engine won’t start processing after the code after the method has been executed
  4. 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
  5. 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
  6. 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
  7. “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.”
  8. Callback • Commonly used in asynchronous operations • When you

    call a function, pass in another function as argument
  9. Example Ext.Ajax.request({            url:  'feed.json',  

             success:  function(response,  opts)  {                  //doSomething()            },            failure:  function(response,  opts)  {                  //doSomething()            }    });
  10. Tip! • Always use a loading spinner before you make

    your asynchronous call. • Never forget to clear the spinner, on success and failure.
  11. 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
  12. 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);   }
  13. Callback horror • Unmaintainable / unreadable code due too many

    nested callbacks. • This is where JavaScript promises might become handy!
  14. 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.
  15. 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
  16. 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!
  17. 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!"));      }   });  
  18. How to use: p.then(function(result)  {      console.log(result);  //  "OK"

      },  function(err)  {      console.log(err);  //  Error:  "Oh  no!"   });
  19. 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.
  20. 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;   });
  21. 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;   }
  22. 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
  23. 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);                        }                }         });             });          }
  24. Use Ext.Promise this.requestUserName().then(function(records){      if(records){        

     //do  something      }   },  function(error){      //throw  error   });
  25. Ext.Ajax built-in Promises Ext.Ajax.request({          url:  'feed.json',

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

             //  use  response   }).always(function()  {        //  clean-­‐up  logic,  regardless  the  outcome   }).otherwise(function(reason){        //  handle  failure   });
  27. 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 • …
  28. 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
  29. Deferreds • mechanism used to create new Promises with Ext

    JS 6 • Promises with additional features
  30. 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    }
  31. Async JavaScript Events • Observer Pattern. Users, System and the

    LifeCycle can throw events, which are asynchronous. - There is no success or failure.
  32. Async JavaScript Callbacks • Asynchronous JS. You pass a function

    in a function, deal with on success or failure.
  33. Async JavaScript Promises • The result of a task, which

    can be fulfilled or rejected. Promises are chain-able.
  34. 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