JavaScript Promises - Thinking Sync in an Async World

2956e2cd2664630aa968b92bbb645f2f?s=47 Kerrick Long
February 06, 2014

JavaScript Promises - Thinking Sync in an Async World

Presented at the STL Ember.js Meetup on 2014-02-06. Video: http://youtu.be/wc72cyYt8-c

2956e2cd2664630aa968b92bbb645f2f?s=128

Kerrick Long

February 06, 2014
Tweet

Transcript

  1. JavaScript Promises Thinking Sync in an Async World then

  2. Kerrick Long Things I make and do Where to find

    me online twitter.com/KerrickLong github.com/Kerrick Lead Front-end Developer! at Second Street KerrickLong.com www. meetup.com/STLEmber
  3. try {! console.log(getLatestGrade(getStudent(name)));! }! catch (error) {! logError(error);! }! finally

    {! logOut();! }!
  4. try {! console.log(getLatestGrade(getStudent(name)));! }! catch (error) {! logError(error);! }! finally

    {! logOut();! }! XMLHttpRequest
  5. getStudent(name, function(student) {! getLatestGrade(student, function(grade) {! console.log(grade);! logOut();! });! });!

  6. var handleError = function(error) {! logError(error);! logOut();! };! getStudent(name, function(error,

    student) {! if (error) return handleError(error);! getLatestGrade(student, function(error, grade) {! if (error) return handleError(error);! console.log(grade);! logOut();! });! });!
  7. var handleError = function(error) {! logError(error);! logOut();! };! getStudent(name, {!

    error: handleError,! success: function(student) {! getLatestGrade(student, {! error: handleError! success: function(grade) {! console.log(grade);! logOut();! },! })! },! });!
  8. try {! console.log(getLatestGrade(getStudent(name)));! }! catch (error) {! logError(error);! }! finally

    {! logOut();! }! Awesome
  9. var handleError = function(error) {! logError(error);! logOut();! };! getStudent(name, {!

    error: handleError,! success: function(student) {! getLatestGrade(student, {! error: handleError! success: function(grade) {! console.log(grade);! logOut();! },! })! },! });! Awkward.
  10. getStudent(name)! .then(getLatestGrade)! .then(console.log)! .catch(logError)! .then(logOut)! ;! Promises

  11. None
  12. Promise Basics

  13. Promise Basics Consuming Promises

  14. Promise Basics Consuming Promises Creating Promises

  15. Promise Basics Consuming Promises Creating Promises Advanced Techniques

  16. Promise Basics

  17. Getting Promises

  18. None
  19. RSVP.js Q.js • Bluebird

  20. RSVP.js Q.js • Bluebird Promises/A+

  21. Promise Guarantees

  22. Always Async

  23. Always Async Returns a Promise

  24. Always Async Returns a Promise Handled Once

  25. Always Async Returns a Promise Handled Once Then’able

  26. Promise States

  27. Promise States Pending Fulfilled Rejected

  28. Promise States Pending Fulfilled Rejected } Settled

  29. Promise States Pending Fulfilled Rejected

  30. Promise States Pending Fulfilled Rejected Value Reason

  31. Promise States Pending Fulfilled Rejected Return Value Thrown Exception

  32. Consuming Promises

  33. Promise Prototype Methods

  34. getJSON('/comments')! .then(onFulfilled, onRejected) Promise.prototype.then

  35. getJSON('/comments')! .then(function(comments) {! if (comments) return 'Good'! else throw new

    Error('Bad')! }, function(reason) {! // handle getJSON errors! }) Promise.prototype.then
  36. getJSON('/comments')! .then(fulfillOne, rejectOne)! .then(fulfillTwo)! .then(null, rejectTwo) Promise.prototype.then

  37. getJSON('/comments')! .then(fulfillOne, rejectOne)! .then(fulfillTwo)! .then(null, rejectTwo) Promise.prototype.then THROW

  38. getJSON('/comments')! .then(fulfillOne, rejectOne)! .then(fulfillTwo)! .then(null, rejectTwo) Promise.prototype.then THROW

  39. getJSON onFulfilled onRejected getJSON onFulfilled onRejected

  40. getJSON('/comments') // waiting...! .then(extractFirstId)! .then(getCommentById) // waiting...! .then(showComment) Promise.prototype.then

  41. var promise = getJSON('/comments');! somethingElse();! promise.then(onFulfilled, onRejected); Promise.prototype.then

  42. getJSON('/comments')! .then(null, onRejected) Promise.prototype.catch

  43. getJSON('/comments')! .catch(onRejected) Promise.prototype.catch

  44. Promise Static Methods

  45. Promise.cast('Hi you!')! .then(onFulfilled, onRejected) Promise.cast

  46. Promise.cast(seededRandom(42))! .then(onFulfilled, onRejected) Promise.cast

  47. Promise.cast($.ajax(config))! .then(onFulfilled, onRejected) Promise.cast

  48. $.ajax(config)! .then(onFulfilled, onRejected)

  49. $.ajax(config)! .then(onFulfilled, onRejected) Lies, all LIES!

  50. Promise.cast($.ajax(config))! .then(onFulfilled, onRejected) Promise.cast

  51. var promises = [ getJSON('/a'),! getJSON('/b'), getJSON('/c') ]! ! Promise.all(promises)!

    .then(allFulfilled, firstRejected) Promise.all
  52. var promises = [ getJSON('/a'),! 'Hi you!', 42, getJSON('/c') ]!

    ! Promise.all(promises)! .then(allFulfilled, firstRejected) Promise.all
  53. var promises = [ saveTo(server1),! saveTo(server2), saveTo(server3) ]! ! Promise.race(promises)!

    .then(firstFulfilled, firstRejected) Promise.race
  54. Creating Promises

  55. new Promise()

  56. function() {! var name = prompt('Your name?')! if (!name)! throw

    new Error('Rude user!')! else! return name! } new Promise()
  57. new Promise(function(fulfill, reject) {! var name = prompt('Your name?')! if

    (!name)! throw new Error('Rude user!')! else! return name! }) new Promise()
  58. new Promise(function(fulfill, reject) {! var name = prompt('Your name?')! if

    (!name)! reject(new Error('Rude user!'))! else! fulfill(name)! }) new Promise()
  59. Shortcuts

  60. new Promise(function(fulfill, reject) {! fulfill(something)! }) Promise.resolve()

  61. new Promise(function(fulfill, reject) {! fulfill(something)! })! Promise.resolve(something) Promise.resolve()

  62. new Promise(function(fulfill, reject) {! reject(something)! }) Promise.reject()

  63. new Promise(function(fulfill, reject) {! reject(something)! })! Promise.reject(something) Promise.reject()

  64. Advanced Techniques

  65. this.get('name') // 'Kerrick'! ! getJSON('/comments')! .then(function(comments) {! this.get('name') // throws!

    }) this and bind()
  66. this.get('name') // 'Kerrick'! var self = this! getJSON('/comments')! .then(function(comments) {!

    self.get('name') // 'Kerrick'! }) this and bind()
  67. this.get('name') // 'Kerrick'! ! getJSON('/comments')! .then(function(comments) {! this.get('name') // 'Kerrick'!

    }.bind(this)) this and bind()
  68. getJSON('/comments')! .then(function(comments) {! throw new Error('Hello?')! }) Absorbed Rejections

  69. getJSON('/comments')! .then(function(comments) {! throw new Error('Hello?')! })! .catch(console.error.bind(console)) Absorbed Rejections

  70. getStudent(name) // <Promise>! .then(getLatestGrade)! .then(log)! .catch(logError)! .then(logOut) Promise-aware Functions

  71. log(getLatestGrade(getStudent(name)))! .catch(logError)! .then(logOut) Promise-aware Functions

  72. function getLatestGrade(promise) {! return Promise.cast(promise)! .then(function(value) {! // getLatestGrade Logic!

    })! } Promise-aware Functions