Date post: | 15-Jan-2015 |
Category: |
Technology |
Upload: | - |
View: | 2,129 times |
Download: | 0 times |
JavaScript Essential Patternsothree @ OSDC 2012
Who am I
• othree
• MozTW member
• F2E at HTC
• http://blog.othree.net
Evolution of the Web
1990 1995 2003 2005
WWWBrowser Wars
Web StandardsWeb Applications
2006
Web 2.0
2010
Mobile
Web Applications
Text
Problem to F2E
• Large scale application never seen on Web
But
• The problem F2Es face today already exists
What is Pattern
• A general reusable solution to a commonly occurring problem within a given context in software design.
http://en.wikipedia.org/wiki/Software_design_pattern
GOF Book, 1994
Browser Environment
• Async
• Event Driven
• Async
• Source Code from Internet
• Async
• Business Logic on Server
Patterns to Talk Today
• Custom Event
• Deferred
• PubSub
Custom Event
http://www.flickr.com/photos/swehrmann/6009646752
Event
• Something happens to an element, to the main document, or to the browser window and that event triggers a reaction.
http://www.yuiblog.com/blog/2007/01/17/event-plan/
Native Events
• DOM Events
• UI
• UI logic
• mutation
• ...
• BOM Events
• load
• error
• history
• ...
Problem of IE
• Didn’t follow the W3C DOM standard
• Memory leaks
• Not support bubbling/capturing
• ‘this’ is window, not element
• ‘event’ is different
http://www.quirksmode.org/blog/archives/2005/08/addevent_consid.html
Dean Edward’s Add Event
• Manage callback functions
• Fallback to elem.onevent = function () { ... }
• Only one function for each event
http://dean.edwards.name/weblog/2005/10/add-event2/
jQuery’s Event
• Normalize event object
• ‘trigger’ method to fire specific event
‘trigger’ Method
• Can fire any event as you wish
• Even none native event name works
Custom Event
• An event name is defined by you, triggered by you
When to Trigger
• State/Value change
Observer
• Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
GoF Book
Example: Backbone
• A driver model
• A car model
• Driver’s tension will get higher when shift gear
Drivervar Driver = Backbone.Model.extend( defaults: { tension: 0 }, tensionUp: function () { this.set({ tension: this.get('tension') + 1 }); });
Carvar Car = Backbone.Model.extend( defaults: { gear: 'P' });
Observervar driver = new Driver(), car = new Car();
car.on('change:gear', function () { driver.tensionUp();});
//GOcar.set({ gear: 1});
Advantages
• Loose coupling
• Prevent nested codes
Deferred
http://www.flickr.com/photos/gozalewis/3256814461/
History
• a.k.a Promise
• Idea since 1976 (Call by future)
• Dojo 0.9 (2007), 1.5 (2010)
• jQuery 1.5 (2011)
• CommonJS Promises/A
What is Deferred
• In computer science, future, promise, and delay refer to constructs used for synchronization in some concurrent programming languages.
http://en.wikipedia.org/wiki/Futures_and_promises
Example: Image Loaderfunction imgLoader(src) { var _img = new Image(), _def = $.Deferred(); _img.onload = _def.resolve; //success _img.onerror = _def.reject; //fail
_img.src = src return _def;}
Use Image LoaderimgLoader('/images/logo.png').done(function () {
$('#logo').fadeIn();
}).fail(function () {
document.location = '/404.html';
});
jQuery Deferred
• Multiple callback functions
• Add callbacks at any time
• jQuery.when
http://api.jquery.com/category/deferred-object/
Image Loader with Cachefunction imgLoader(src) { if (imgLoader[src]) { return imgLoader[src]; }
var _img = new Image(), _def = $.Deferred(); imgLoader[src] = _def; _img.onload = _def.resolve; //success _img.onerror = _def.reject; //fail
_img.src = src return _def;}
Use Image LoaderimgLoader('/images/logo.png').done(function () { $('#logo').fadeIn();}).fail(function () { document.location = '/404.html';});
imgLoader('/images/logo.png').done(function () { App.init();});
imgLoader('/images/logo.png').fail(function () { App.destroy();});
jQuery.when$.when(
$.getJSON('/api/jedis'), $.getJSON('/api/siths'), $.getJSON('/api/terminators')
).done(function (jedis, siths, terminators) {
// do something....
});
Advantages
• Manage callbacks
• Cache results
• $.when
PubSub
http://www.flickr.com/photos/birdfarm/519230710/
Case
• A module know when user signin
• X, Y modules need to know when user signin
• A should not fail when X or Y fails
Without PubSub
signin
signin
A Y
X
ZB
X, Y depends on A
PubSubSubscribe Event Only
PubSub
A Y
X
ZB
PubSubsubscribe
‘signin’
subscribe‘signin’
A Y
X
ZB
PubSubpublish‘signin’A Y
X
ZB
PubSubsignin
signin
A Y
X
ZB
Publish/Subscribe
• Mediator + Observer
• Easy to implement
http://addyosmani.com/blog/jqcon-largescalejs-2012/
$(document).trigger('eventName');//equivalent to $.publish('eventName')$(document).on('eventName',...);//equivalent to $.subscribe('eventName',...)
// Using .on()/.off() from jQuery 1.7.1(function($) { var o = $({}); $.subscribe = function() { o.on.apply(o, arguments); }; $.unsubscribe = function() { o.off.apply(o, arguments); }; $.publish = function() { o.trigger.apply(o, arguments); };}(jQuery));
// Multi-purpose callbacks list object// Pub/Sub implementation:
var topics = {};
jQuery.Topic = function( id ) { var callbacks, topic = id && topics[ id ]; if ( !topic ) { callbacks = jQuery.Callbacks(); topic = { publish: callbacks.fire, subscribe: callbacks.add, unsubscribe: callbacks.remove }; if ( id ) { topics[ id ] = topic; } } return topic;};
//Using Underscore and Backbone
var myObject = {};
_.extend( myObject, Backbone.Events );
//Example
myObject.on('eventName', function( msg ) { console.log( 'triggered:' + msg );});
myObject.trigger('eventName', 'some event');
When to Use
• Module and module have dependency but not really depend on it.
Example: Error Handler
• An module to control the behavior when error occurs
• All other module should call it when something went wrong
• No module should fail because error handler fails
Error Handler Code//Error Handler$.subscribe('AJAXfail', function () { alert('Something wrong!!');});
//Code$.get('/api/siths').fail(function () { $.publish('AJAXfail');});
Advantages
• Loose coupling
• Scalability
Summary
• Control async process using deferred
• Modulize your application
• Decouple using custom event
• Decouple more using pubsub
Further Reading...
http://addyosmani.com/resources/essentialjsdesignpatterns/book/
http://shichuan.github.com/javascript-patterns/
May the Patterns be with You
Questions?
Photos License
• CC License
• http://www.flickr.com/photos/sbisson/298160250/
• http://www.flickr.com/photos/gozalewis/3256814461/
• http://www.flickr.com/photos/birdfarm/519230710/
• Licensed by Author
• http://www.flickr.com/photos/swehrmann/6009646752