O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

TDC2016POA | Trilha JavaScript - JavaScript Promises na Prática

179 visualizações

Publicada em

JavaScript Promises na Prática

Publicada em: Educação
  • Seja o primeiro a comentar

TDC2016POA | Trilha JavaScript - JavaScript Promises na Prática

  1. 1. Globalcode – Open4education JavaScript Promises Derek Stavis Engenheiro de Software
  2. 2. Globalcode – Open4education Who? Derek Stavis github.com/derekstavis Software Engineer Ruby, JavaScript, Python, C Node, React & Webpack Advocate
  3. 3. Globalcode – Open4education How have you been doing asynchronous JavaScript?
  4. 4. Globalcode – Open4education How have you been doing continuation passing?
  5. 5. Globalcode – Open4education Using callback functions // In the browser setTimeout(function () { // Will be called in the future }, 2000); // In the server fs.readFile('file.txt', function () { // Will be called when file.txt is read });
  6. 6. Globalcode – Open4education Node.js callback standard fs.readFile('file.txt', function (err, data) { // If an error occurred, err will have a value // Always check for errors using if clauses })
  7. 7. Globalcode – Open4education Node.js callback scenario Let’s say we have a fetch function It does plain HTTP GET Accepts a URL and a callback Callback receives error and response fetch ('url', function (err, res) { })
  8. 8. Globalcode – Open4education Node.js callback scenario fetch('/users/session', function (sessionError, user) { if (sessionError) { alert('Error fetching session') return } fetch('/users/' + user.id + '/posts', function (userErr, posts) { if (userErr) { alert('Error fetching user posts') return } renderUserPosts(posts) }) })
  9. 9. Globalcode – Open4education Node.js callback hell
  10. 10. Globalcode – Open4education How could we flatten that tree?
  11. 11. Globalcode – Open4education new Promise()
  12. 12. Globalcode – Open4education Formal definition "A promise represents the eventual result of an asynchronous operation."
  13. 13. Globalcode – Open4education Formal definition "A promise represents the eventual result of an asynchronous operation."
  14. 14. Globalcode – Open4education Enter Promises An object which represents and manage the lifecycle of a future result
  15. 15. Globalcode – Open4education Promise states Pending Fulfilled Rejected
  16. 16. Globalcode – Open4education Promise states Promises aren't reusable
  17. 17. Globalcode – Open4education Promise API // New Promises start in "Pending" state new Promise(function (resolve, reject) { // Transition to "Rejected" state reject(new Error('A meaningful error')) // Transition to "Fulfilled" state resolve({ my: 'data' }) })
  18. 18. Globalcode – Open4education Promise API var promise = new Promise(...) promise.then(function (result) { console.log(result) }) => { my: "data" }
  19. 19. Globalcode – Open4education Promise API var promise = new Promise(...) promise.catch(function (error) { console.log(error.message) }) => A meaningful error
  20. 20. Globalcode – Open4education Promise API Node.js callbacks can be easily wrapped in promises
  21. 21. Globalcode – Open4education Promise API function fetch (url) { return new Promise(function (resolve, reject) { request(url, function (err, data) { if (err) { reject(err) } else { resolve(data) } }) }
  22. 22. Globalcode – Open4education Promise API Every .then and .catch return a new promise, so promises are chainable
  23. 23. Globalcode – Open4education Flattening the tree function fetchPosts (user) { return fetch('/users/' + user.id + '/posts') } function fetchSession () { return fetch('/users/session') } fetchSession() .catch(handleSessionError) .then(fetchPosts) .catch(handlePostsError) .then(renderUserPosts)
  24. 24. Globalcode – Open4education Flattening the tree Chaining allows flattening the callback hell and make continuation passing look sequential
  25. 25. Globalcode – Open4education Flattening the tree const fetchTuples = () => Promise.resolve([ [1, 1], [2, 2], [6, 4] ])
  26. 26. Globalcode – Open4education Chaining (a.k.a. sequence monad) const makeObject = e => ({ l: e[0], r: e[1] }) const attachPlus = e => merge(e, { plus: e.l + e.r }) const attachMinus = e => merge(e, { minus: e.l - e.r }) const attachTimes = e => merge(e, { times: e.l * e.r }) const attachDivide = e => merge(e, { divide: e.l / e.r }) fetchTuples() .then(map(makeObject)) .then(map(attachPlus)) .then(map(attachMinus)) .then(map(attachTimes)) .then(map(attachDivide)) .then(console.log.bind(console))
  27. 27. Globalcode – Open4education Chaining (a.k.a. sequence monad) { l: 1, r: 1, plus: 2, minus: 0, times: 1, divide: 1 } { l: 2, r: 2, plus: 4, minus: 0, times: 4, divide: 1 } { l: 6, r: 4, plus: 10, minus: 2, times: 24, divide: 1.5 }
  28. 28. Globalcode – Open4education Promise Implementation Promise is a specification
  29. 29. Globalcode – Open4education Promise Implementation There are a handful of Promise implementations
  30. 30. Globalcode – Open4education Promise Implementation Solving different issues, focusing on different areas
  31. 31. Globalcode – Open4education Promise Implementation So I have to be tied to a single implementation?
  32. 32. Globalcode – Open4education NOT HERE
  33. 33. Globalcode – Open4education Promises/A+ Contract https://promisesaplus.com
  34. 34. Globalcode – Open4education Promises/A+ Contract Promises/A+ provides interface and behaviour specification for interoperable promises
  35. 35. Globalcode – Open4education Promises/A+ Contract So you are free to use the implementation which better fit your needs while keeping your code compatible
  36. 36. Globalcode – Open4education Promises/A+ Contract This contract was created because there was no native Promise specification in ECMAScript
  37. 37. Globalcode – Open4education ECMAScript 2015 Promise Since ECMAScript 2015 the Promise object was included in the spec https://tc39.github.io/ecma262/#sec-promise- constructor
  38. 38. Globalcode – Open4education ECMAScript 2015 Promise It allows more fun stuff do be done
  39. 39. Globalcode – Open4education ECMAScript 2015 Promise Waiting for multiple Promises
  40. 40. Globalcode – Open4education Waiting for multiple Promises var promises = [ new Promise(function (resolve, reject) { setTimeout(resolve, 1000); }), new Promise(function (resolve, reject) { setTimeout(resolve, 2000); }) ] Promise.all(promises).then(function () { console.log('Ran after 2 seconds') })
  41. 41. Globalcode – Open4education ECMAScript 2015 Promise Racing multiple Promises
  42. 42. Globalcode – Open4education Racing multiple Promises var promises = [ new Promise(function (resolve, reject) { setTimeout(resolve, 1000); }), new Promise(function (resolve, reject) { setTimeout(resolve, 2000); }) ] Promise.race(promises).then(function () { console.log('Ran after 1 second') })
  43. 43. Globalcode – Open4education You should definitely look into Promises
  44. 44. Globalcode – Open4education Because there's even more!
  45. 45. Globalcode – Open4education Bluebird A complete Promise library http://bluebirdjs.com
  46. 46. Globalcode – Open4education Bluebird Promise Catch rejections like exceptions
  47. 47. Globalcode – Open4education Fine-grained exceptions function SessionError(message) { this.message = message this.name = "SessionError" Error.captureStackTrace(this, SessionError) } SessionError.prototype = Object.create(Error.prototype) SessionError.prototype.constructor = SessionError
  48. 48. Globalcode – Open4education Fine-grained exceptions function fetchPosts (user) { throw new PostsError('could not fetch posts') } function fetchSession () { return new SessionError('could not fetch session') } fetchSession() .then(fetchPosts) .then(renderPosts) .catch(SessionError, handleSessionError) .catch(PostsError, handlePostsError)
  49. 49. Globalcode – Open4education Bluebird Promise Spread Promise.all result as parameters
  50. 50. Globalcode – Open4education Parameter spread Promise.all([ download('http://foo.bar/file.tar.gz'), download('http://foo.bar/file.tar.gz.sig') ]).spread((file, signature) => sign(file) == signature ? Promise.resolve(file) : Promise.reject('invalid signature') )
  51. 51. Globalcode – Open4education Bluebird Promise Use .all & .spread for dynamic amount of promises When doing fixed number of promises use .join
  52. 52. Globalcode – Open4education Join promises results Promise.join( download('http://foo.bar/file.tar.gz'), download('http://foo.bar/file.tar.gz.sig'), (file, signature) => sign(file) == signature ? Promise.resolve(file) : Promise.reject('invalid signature') )
  53. 53. Globalcode – Open4education Bluebird Promise Resolve objects with promises
  54. 54. Globalcode – Open4education Join promises results Promise.props({ file: download('http://foo.bar/file.tar.gz'), sig: download('http://foo.bar/file.tar.gz.sig') }).then(data => sign(data.file) == data.sig ? Promise.resolve(file) : Promise.reject('invalid signature') )
  55. 55. Globalcode – Open4education Bluebird Promise Do some .reduce with promises
  56. 56. Globalcode – Open4education Reduce promises results const urls = fetchProjects() Promise.reduce(urls, (total, url) => fetch(url).then(data => total + data.stars), 0)
  57. 57. Globalcode – Open4education HTML Fetch A Promise approach to HTTP requests https://fetch.spec.whatwg.org
  58. 58. Globalcode – Open4education #DeprecateXHR fetch('/users.json') .then(function(response) { return response.json() }).then(function(json) { console.log('parsed json', json) }).catch(function(ex) { console.log('parsing failed', ex) })
  59. 59. Globalcode – Open4education #DeprecateXHR fetch('/users.json') .then(function(response) { return response.json() fetch('/users.json') .then(function(response) { return response.json() }).then(function(json) { console.log('parsed json', json) }).catch(function(ex) { console.log('parsing failed', ex) })
  60. 60. Globalcode – Open4education #DeprecateXHR fetch is growing so powerful
  61. 61. Globalcode – Open4education #DeprecateXHR $ telnet mockbin.org 80 GET /bin/2294df68-ae10-4336-a732-3170597543a9 HTTP/1.1 Accept: */* Host: mockbin.org HTTP/1.1 200 OK Content-Type: text/html Custom-Header: CustomValue {"fetch": "is so cool"}
  62. 62. Globalcode – Open4education #DeprecateXHR fetch promise resolve as soon as headers are ready
  63. 63. Globalcode – Open4education Demo Fetching stuff from Github https://github.com/derekstavis/ promises-on-the-browser
  64. 64. Globalcode – Open4education Thanks for watching Questions? github.com/derekstavis twitter.com/derekstavis facebook.com/derekstavis

×