Javascript essential-pattern

Post on 15-Jan-2015

2.124 views 0 download

Tags:

description

Talk about the custom event, deferred and pubsub.

Transcript of Javascript essential-pattern

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://leanpub.com/asyncjs

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