Your SlideShare is downloading. ×
Building Smart Async Functions For Mobile
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Building Smart Async Functions For Mobile

1,615
views

Published on

Published in: Technology, Design

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,615
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
23
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. BUILDING SMART ASYNCFUNCTIONS FOR MOBILE Glan Thomas Mountain View JavaScript Meetup Group Aug 10, 2011
  • 2. TYPICAL ASYNC FUNCTIONSgetJSON(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. INTERFACESCache Interface Queue Interface • get(key) • add(item) • set(key, value) • remove() • delete(key)
  • 8. DECORATORS
  • 9. WHAT JUST HAPPENED?jQuery.get CacheDecorator getCached
  • 10. USAGEvar cache = new Cache(),myGet = jQuery.get;myGet = new CacheDecorator(myGet, cache);myGet(url, successFunction);
  • 11. CACHE DECORATORvar 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. STACKINGvar cache = new Cache(), filter = new Filter(),myGet = jQuery.get;myGet = new FilterDecorator(myGet, filter);myGet = new CacheDecorator(myGet, cache);myGet(url, successFunction);
  • 13. FILTER DECORATORvar 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 DECORATORvar 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)
  • 17. QUESTIONS?
  • 18. CACHE IMPLEMENTATIONCache.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 IMPLEMENTATIONvar 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 DECORATORvar 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); } }); } };};

×