Movatterモバイル変換


[0]ホーム

URL:


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

Web app with functional programming

Avatar for Yu I. Yu I.
June 27, 2014

Web app with functional programming

Avatar for Yu I.

Yu I.

June 27, 2014
Tweet

More Decks by Yu I.

See All by Yu I.

Other Decks in Programming

See All in Programming

Featured

See All Featured

Transcript

  1. Web app with functional programming

  2. Motivation

  3. grunt-browserify is now super cool!

  4. Functional programming seems super cool!

  5. None
  6. http://japboy.github.io/slidr

  7. In case of another Tumblr photo viewer » Made with:

    » D3.js (as DOM shorthands) » Underscore (as functional toolchain) » Q (as Promise object) » Think of what functional is
  8. D3.js as DOM shorthands » Bare DOM APIs are too

    verbose... » DOM APIs are object-oriented and should be wrapped as functional to be cool! » DOM shorthands will be reinventing wheel of jQuery... » Functions of jQuery are more like procedural and don't seem cool... » Functions of D3.js seems declarative and so cool!
  9. Underscore as functional toolchain » Very useful in case to

    read JSONs from ReST APIs » "Functional JavaScript" says Underscore is promising to be functional
  10. Q as Promise object » Asynchronous process needs any wrapper

    to be functional » Q is portable Promise implementation for client- and server-sides
  11. Q is great if functions are idempotent

  12. Idempotent?

  13. Idempotent function f (a, b) { return a + b;

    } f(1, 2); // => 3 Same result as always!
  14. Changed var x = 1; function f (a, b) {

    return a + b + x; } f(1, 2); // => 4 Result depends on the value of x
  15. Idempotent Promise object function submit (query) { var dfr =

    Q.defer(), form = d3.select('.search'), input = form.select('.search__input'); if (query) { _.defer(function () { input.property('value', query); form.classed({ 'position--in': false, 'position--out': true }); dfr.resolve(query); }); } else { form.on('submit', function (d, i) { var value = input.property('value'); d3.event.preventDefault(); form.on('submit', null); form.classed({ 'position--in': false, 'position--out': true }); global.location.hash = '#/' + global.encodeURIComponent(value); dfr.resolve(value); }); } return dfr.promise; }
  16. Chaining Promise objects function init () { Q.all([ helper.dom(), helper.sleep(1500)

    ]) .then(load) // Initial process .then(hash) .then(submit) // Repeated process .then(api) .then(cache) .then(show); } Easy to read what is proceeding!
  17. Reuse of chaining Promises function show () { submit() //

    Repeated process .then(api) .then(cache) .then(show); } Easy to build them up again!
  18. Wrap anything that are complicated

  19. Complicated?

  20. Wrap with Object-oriented Class class Blog extends helper.mixOf helper.Base, EventEmitter

    constructor: (domain, consumerKey) -> super() @consumerKey_ = consumerKey @domain_ = domain @total_ = 20 destroy: => @removeAllListeners() request: (type, offset=0) => consumerKey = @get 'consumerKey' domain = @get 'domain' uri = "http://api.tumblr.com/v2/blog/" uri += "#{domain}/posts/#{type}?api_key=#{consumerKey}&offset=#{offset}" done = (data) => if 200 is data.meta.status @set 'total', data.total_posts return @emit 'load', data.response @emit 'error', new Error(data.meta.status + ' ' + data.meta.msg) fail = (err) => @emit 'error', err helper.jsonp(uri).then(done, fail)
  21. Make Promise from the Class function api (domain) { var

    dfr = Q.defer(), blog = new Blog(domain, CONSUMER_KEY); blog.on('load', dfr.resolve); blog.on('error', dfr.reject); blog.request('photo', 0); return dfr.promise; }
  22. Create small parts and build them up!

  23. Functional is fun!


[8]ページ先頭

©2009-2025 Movatter.jp