SlideShare a Scribd company logo
BUILDING SMART ASYNC
FUNCTIONS FOR MOBILE
              Glan Thomas
   Mountain View JavaScript Meetup Group
               Aug 10, 2011
TYPICAL ASYNC FUNCTIONS
getJSON(url, [data,] [success(data, textStatus, jqXHR),] [dataType])

get(url, [data,] [success(data, textStatus, jqXHR),] [dataType])

post(url, [data,] [success(data, textStatus, jqXHR),] [dataType])
ASYNC PROBLEMS

• Requires   an HTTP request

• Requires   a network connection

• Cross   domain origin
OBJECTIVES

• Minimize   HTTP requests

• Make    things work even if you are offline

• Avoid cluttering up the app’s controllers with online/offline
 conditionals

• Preserve   original API signatures
  getJSON( url, [data,] [success,] [cache,] [filter,] [keyboardcat] )
WHAT CAN WE DO?

• Cache    - Keep a local copy of the data

• Queue     - For sending to the server later

• Merge    - Combine requests into one

• Filter   - Transform the incoming data

• AB   Testing - Provide different data for different users

• Versioning     - Making sure you hit the right endpoints
TECHNIQUES

• Interfaces   - for utility objects

• Decorators    - for augmenting async functions

• Delegation    - to utility object
INTERFACES

Cache Interface        Queue Interface

 • get(key)             • add(item)

 • set(key,   value)    • remove()

 • delete(key)
DECORATORS
WHAT JUST HAPPENED?




jQuery.get   CacheDecorator   getCached
USAGE

var cache = new Cache(),

myGet = jQuery.get;

myGet = new CacheDecorator(myGet, cache);

myGet(url, successFunction);
CACHE DECORATOR
var CacheDecorator = function (func, cache) {
    'use strict';
    return function (url, success) {
        var data = cache.get(url);
        if (data) {
            success(data, 'hit');
        } else {
            func(url, function (data) {
                 cache.set(url, data);
                 if (typeof success === 'function') {
                     success.apply(this, arguments);
                 }
            });
        }
    };
};
STACKING

var cache = new Cache(), filter = new Filter(),

myGet = jQuery.get;

myGet = new FilterDecorator(myGet, filter);

myGet = new CacheDecorator(myGet, cache);

myGet(url, successFunction);
FILTER DECORATOR
var FilterDecorator = function (func, filter) {
    'use strict';
    return function (url, success) {
        func(url, function (data) {
            data = filter(url, data);
            if (typeof success === 'function') {
                success.apply(this, arguments);
            }
        });
    };
};
QUEUE DECORATOR
var QueueDecorator = function (func, queue) {
    'use strict';
    return function (url, data, success) {
        queue.add({'func': func, 'args' : arguments});
        success({}, 'queued');
    };
};
TAKEAWAYS

• Usedecorators to enhance existing asynchronous functions
 without altering their signatures.

• Delegate
         functionality to dedicated utility objects (Caching/
 Queuing).

• Define    interfaces for utility objects.

• Stack   decorators to combine functionality.
SOME THINGS WE SKIPPED

• Cross   domain origin

• Error   and failure states

• Specificimplementations of Cache and Queue classes
 (LocalStorage/SQLite)

• Enforcing   of interfaces
 (see ‘Pro JavaScript Design Patterns’, Ross Harmes and Dustin Diaz, Apress, 2008)
QUESTIONS?
CACHE IMPLEMENTATION
Cache.prototype = {
    set : function (key, value) {
        var package = {};
        package.type = typeof value;
        package.value = (package.type === 'object') ? JSON.stringify(value) : value;
        localStorage[this._hash(key)] = JSON.stringify(package);
    },
    get : function (key) {
        var package;
        if (this._exists(key)) {
            try {
                package = JSON.parse(localStorage[this._hash(key)]);
            } catch (e) {
                this.remove(key);
                return false;
            }
            return (package.type === 'object') ? JSON.parse(package.value) : package.value;
        }
        return false;
    },
    remove : function (key) {
        if (this._exists(key)) {
            delete localStorage[this._hash(key)];
        }
    }
}
QUEUE IMPLEMENTATION
var Queue = function() {};
Queue.prototype = new Array();

Queue.prototype.add = function (item) {
   this.push(item);
};
Queue.prototype.remove = function () {
    return this.shift();
};
Queue.prototype.goOnline = function () {
    var self = this, success;
    if(item = this[0]) {
       success = item.args[2];
       item.args[2] = function () {
          success.apply(this, arguments);
          self.remove();
          self.goOnline();
       };
       item.func.apply(this, item.args);
    }
};

var queue = new Queue();

document.body.addEventListener("online", function () {
   queue.goOnline();
}, false);
OFFLINE DECORATOR
var OfflineDecorator = function (func, offLine) {
    'use strict';
    return function (url, success) {
        if (offLine) {
            success({}, 'offline');
        } else {
            func(url, function (data) {
                 if (typeof success === 'function') {
                     success.apply(this, arguments);
                 }
            });
        }
    };
};

More Related Content

PDF
#ajn3.lt.marblejenka
PDF
Appengine Java Night #2b
PDF
Appengine Java Night #2a
PDF
JavaScript Unit Testing with Jasmine
PDF
Source Code for Dpilot
PDF
Dpilot Source Code With ScreenShots
PDF
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
PPTX
Rxjs marble-testing
#ajn3.lt.marblejenka
Appengine Java Night #2b
Appengine Java Night #2a
JavaScript Unit Testing with Jasmine
Source Code for Dpilot
Dpilot Source Code With ScreenShots
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Rxjs marble-testing

What's hot (20)

PDF
Tweaking the interactive grid
PDF
"Inside The AngularJS Directive Compiler" by Tero Parviainen
PDF
ReactでGraphQLを使っている
PDF
React lecture
PPTX
Angular mix chrisnoring
PDF
Rxjs vienna
PDF
PGConf APAC 2018 - Lightening Talk #2 - Centralizing Authorization in PostgreSQL
KEY
Polyglot parallelism
PDF
An introduction to property-based testing
PPTX
Firebase ng2 zurich
PDF
PerlApp2Postgresql (2)
PDF
Speed Things Up with Transients
PDF
PostgreSQL Open SV 2018
PDF
My Top 5 APEX JavaScript API's
PPTX
Owl: The New Odoo UI Framework
PPT
Testing Javascript with Jasmine
PDF
Lucene
PDF
Clustering your Application with Hazelcast
ODP
Europython 2011 - Playing tasks with Django & Celery
PDF
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Tweaking the interactive grid
"Inside The AngularJS Directive Compiler" by Tero Parviainen
ReactでGraphQLを使っている
React lecture
Angular mix chrisnoring
Rxjs vienna
PGConf APAC 2018 - Lightening Talk #2 - Centralizing Authorization in PostgreSQL
Polyglot parallelism
An introduction to property-based testing
Firebase ng2 zurich
PerlApp2Postgresql (2)
Speed Things Up with Transients
PostgreSQL Open SV 2018
My Top 5 APEX JavaScript API's
Owl: The New Odoo UI Framework
Testing Javascript with Jasmine
Lucene
Clustering your Application with Hazelcast
Europython 2011 - Playing tasks with Django & Celery
Codepot - Pig i Hive: szybkie wprowadzenie / Pig and Hive crash course
Ad

Similar to Building Smart Async Functions For Mobile (20)

PPTX
Taming that client side mess with Backbone.js
PDF
Understanding backbonejs
KEY
Backbone.js Simple Tutorial
PDF
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
PDF
Ten useful JavaScript tips & best practices
PDF
Clean Javascript
PPTX
AngularJS - $http & $resource Services
PDF
Migrating from Flux to Redux. Why and how.
PPTX
Build Lightweight Web Module
PPTX
LinkedIn TBC JavaScript 100: Functions
PDF
Google App Engine Developer - Day3
PDF
Spring data requery
PDF
Virtual Madness @ Etsy
PDF
Stop Making Excuses and Start Testing Your JavaScript
PDF
JavaScript Fundamentals with Angular and Lodash
PPTX
AngularJS Services
KEY
Backbone.js
PDF
Bindings: the zen of montage
PDF
Redux vs Alt
PDF
Akka Cluster in Java - JCConf 2015
Taming that client side mess with Backbone.js
Understanding backbonejs
Backbone.js Simple Tutorial
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
Ten useful JavaScript tips & best practices
Clean Javascript
AngularJS - $http & $resource Services
Migrating from Flux to Redux. Why and how.
Build Lightweight Web Module
LinkedIn TBC JavaScript 100: Functions
Google App Engine Developer - Day3
Spring data requery
Virtual Madness @ Etsy
Stop Making Excuses and Start Testing Your JavaScript
JavaScript Fundamentals with Angular and Lodash
AngularJS Services
Backbone.js
Bindings: the zen of montage
Redux vs Alt
Akka Cluster in Java - JCConf 2015
Ad

Recently uploaded (20)

PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Machine Learning_overview_presentation.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
cuic standard and advanced reporting.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Empathic Computing: Creating Shared Understanding
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
A Presentation on Artificial Intelligence
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Electronic commerce courselecture one. Pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Cloud computing and distributed systems.
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
A comparative analysis of optical character recognition models for extracting...
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Machine learning based COVID-19 study performance prediction
Machine Learning_overview_presentation.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
cuic standard and advanced reporting.pdf
The AUB Centre for AI in Media Proposal.docx
Empathic Computing: Creating Shared Understanding
Chapter 3 Spatial Domain Image Processing.pdf
A Presentation on Artificial Intelligence
NewMind AI Weekly Chronicles - August'25-Week II
Electronic commerce courselecture one. Pdf
Programs and apps: productivity, graphics, security and other tools
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Diabetes mellitus diagnosis method based random forest with bat algorithm
Per capita expenditure prediction using model stacking based on satellite ima...
“AI and Expert System Decision Support & Business Intelligence Systems”
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Cloud computing and distributed systems.
Building Integrated photovoltaic BIPV_UPV.pdf

Building Smart Async Functions For Mobile

  • 1. BUILDING SMART ASYNC FUNCTIONS FOR MOBILE Glan Thomas Mountain View JavaScript Meetup Group Aug 10, 2011
  • 2. TYPICAL ASYNC FUNCTIONS getJSON(url, [data,] [success(data, textStatus, jqXHR),] [dataType]) get(url, [data,] [success(data, textStatus, jqXHR),] [dataType]) post(url, [data,] [success(data, textStatus, jqXHR),] [dataType])
  • 3. ASYNC PROBLEMS • Requires an HTTP request • Requires a network connection • Cross domain origin
  • 4. OBJECTIVES • Minimize HTTP requests • Make things work even if you are offline • Avoid cluttering up the app’s controllers with online/offline conditionals • Preserve original API signatures getJSON( url, [data,] [success,] [cache,] [filter,] [keyboardcat] )
  • 5. WHAT CAN WE DO? • Cache - Keep a local copy of the data • Queue - For sending to the server later • Merge - Combine requests into one • Filter - Transform the incoming data • AB Testing - Provide different data for different users • Versioning - Making sure you hit the right endpoints
  • 6. TECHNIQUES • Interfaces - for utility objects • Decorators - for augmenting async functions • Delegation - to utility object
  • 7. INTERFACES Cache Interface Queue Interface • get(key) • add(item) • set(key, value) • remove() • delete(key)
  • 9. WHAT JUST HAPPENED? jQuery.get CacheDecorator getCached
  • 10. USAGE var cache = new Cache(), myGet = jQuery.get; myGet = new CacheDecorator(myGet, cache); myGet(url, successFunction);
  • 11. CACHE DECORATOR var CacheDecorator = function (func, cache) { 'use strict'; return function (url, success) { var data = cache.get(url); if (data) { success(data, 'hit'); } else { func(url, function (data) { cache.set(url, data); if (typeof success === 'function') { success.apply(this, arguments); } }); } }; };
  • 12. STACKING var cache = new Cache(), filter = new Filter(), myGet = jQuery.get; myGet = new FilterDecorator(myGet, filter); myGet = new CacheDecorator(myGet, cache); myGet(url, successFunction);
  • 13. FILTER DECORATOR var FilterDecorator = function (func, filter) { 'use strict'; return function (url, success) { func(url, function (data) { data = filter(url, data); if (typeof success === 'function') { success.apply(this, arguments); } }); }; };
  • 14. QUEUE DECORATOR var QueueDecorator = function (func, queue) { 'use strict'; return function (url, data, success) { queue.add({'func': func, 'args' : arguments}); success({}, 'queued'); }; };
  • 15. TAKEAWAYS • Usedecorators to enhance existing asynchronous functions without altering their signatures. • Delegate functionality to dedicated utility objects (Caching/ Queuing). • Define interfaces for utility objects. • Stack decorators to combine functionality.
  • 16. SOME THINGS WE SKIPPED • Cross domain origin • Error and failure states • Specificimplementations of Cache and Queue classes (LocalStorage/SQLite) • Enforcing of interfaces (see ‘Pro JavaScript Design Patterns’, Ross Harmes and Dustin Diaz, Apress, 2008)
  • 18. CACHE IMPLEMENTATION Cache.prototype = { set : function (key, value) { var package = {}; package.type = typeof value; package.value = (package.type === 'object') ? JSON.stringify(value) : value; localStorage[this._hash(key)] = JSON.stringify(package); }, get : function (key) { var package; if (this._exists(key)) { try { package = JSON.parse(localStorage[this._hash(key)]); } catch (e) { this.remove(key); return false; } return (package.type === 'object') ? JSON.parse(package.value) : package.value; } return false; }, remove : function (key) { if (this._exists(key)) { delete localStorage[this._hash(key)]; } } }
  • 19. QUEUE IMPLEMENTATION var Queue = function() {}; Queue.prototype = new Array(); Queue.prototype.add = function (item) { this.push(item); }; Queue.prototype.remove = function () { return this.shift(); }; Queue.prototype.goOnline = function () { var self = this, success; if(item = this[0]) { success = item.args[2]; item.args[2] = function () { success.apply(this, arguments); self.remove(); self.goOnline(); }; item.func.apply(this, item.args); } }; var queue = new Queue(); document.body.addEventListener("online", function () { queue.goOnline(); }, false);
  • 20. OFFLINE DECORATOR var OfflineDecorator = function (func, offLine) { 'use strict'; return function (url, success) { if (offLine) { success({}, 'offline'); } else { func(url, function (data) { if (typeof success === 'function') { success.apply(this, arguments); } }); } }; };